Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

audio-base.hpp 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #ifndef AUDIO_BASE_HPP_INCLUDED
  18. #define AUDIO_BASE_HPP_INCLUDED
  19. #include "CarlaMathUtils.hpp"
  20. extern "C" {
  21. #include "audio_decoder/ad.h"
  22. }
  23. #include "water/threads/ScopedLock.h"
  24. #include "water/threads/SpinLock.h"
  25. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  26. # pragma GCC diagnostic push
  27. # pragma GCC diagnostic ignored "-Weffc++"
  28. #endif
  29. #include "zita-resampler/resampler.h"
  30. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  31. # pragma GCC diagnostic pop
  32. #endif
  33. #if defined(CARLA_OS_WIN)
  34. # include <windows.h>
  35. # define CARLA_MLOCK(ptr, size) VirtualLock((ptr), (size))
  36. #elif !defined(CARLA_OS_WASM)
  37. # include <sys/mman.h>
  38. # define CARLA_MLOCK(ptr, size) mlock((ptr), (size))
  39. #else
  40. # define CARLA_MLOCK(ptr, size)
  41. #endif
  42. // #define DEBUG_FILE_OPS
  43. typedef struct adinfo ADInfo;
  44. struct AudioFilePool {
  45. float* buffer[2];
  46. float* tmpbuf[2];
  47. uint32_t numFrames;
  48. uint32_t maxFrame;
  49. volatile uint64_t startFrame;
  50. water::SpinLock mutex;
  51. #ifdef CARLA_PROPER_CPP11_SUPPORT
  52. AudioFilePool() noexcept
  53. : buffer{nullptr},
  54. tmpbuf{nullptr},
  55. numFrames(0),
  56. maxFrame(0),
  57. startFrame(0),
  58. mutex() {}
  59. #else
  60. AudioFilePool() noexcept
  61. : numFrames(0),
  62. startFrame(0),
  63. mutex()
  64. {
  65. buffer[0] = buffer[1] = nullptr;
  66. tmpbuf[0] = tmpbuf[1] = nullptr;
  67. }
  68. #endif
  69. ~AudioFilePool()
  70. {
  71. destroy();
  72. }
  73. void create(const uint32_t desiredNumFrames, const uint32_t fileNumFrames, const bool withTempBuffers)
  74. {
  75. CARLA_ASSERT(buffer[0] == nullptr);
  76. CARLA_ASSERT(buffer[1] == nullptr);
  77. CARLA_ASSERT(tmpbuf[0] == nullptr);
  78. CARLA_ASSERT(tmpbuf[1] == nullptr);
  79. CARLA_ASSERT(startFrame == 0);
  80. CARLA_ASSERT(numFrames == 0);
  81. CARLA_ASSERT(maxFrame == 0);
  82. buffer[0] = new float[desiredNumFrames];
  83. buffer[1] = new float[desiredNumFrames];
  84. carla_zeroFloats(buffer[0], desiredNumFrames);
  85. carla_zeroFloats(buffer[1], desiredNumFrames);
  86. CARLA_MLOCK(buffer[0], sizeof(float)*desiredNumFrames);
  87. CARLA_MLOCK(buffer[1], sizeof(float)*desiredNumFrames);
  88. if (withTempBuffers)
  89. {
  90. tmpbuf[0] = new float[desiredNumFrames];
  91. tmpbuf[1] = new float[desiredNumFrames];
  92. carla_zeroFloats(tmpbuf[0], desiredNumFrames);
  93. carla_zeroFloats(tmpbuf[1], desiredNumFrames);
  94. CARLA_MLOCK(tmpbuf[0], sizeof(float)*desiredNumFrames);
  95. CARLA_MLOCK(tmpbuf[1], sizeof(float)*desiredNumFrames);
  96. }
  97. const water::GenericScopedLock<water::SpinLock> gsl(mutex);
  98. startFrame = 0;
  99. numFrames = desiredNumFrames;
  100. maxFrame = fileNumFrames;
  101. }
  102. void destroy() noexcept
  103. {
  104. {
  105. const water::GenericScopedLock<water::SpinLock> gsl(mutex);
  106. startFrame = 0;
  107. numFrames = 0;
  108. maxFrame = 0;
  109. }
  110. if (buffer[0] != nullptr)
  111. {
  112. delete[] buffer[0];
  113. buffer[0] = nullptr;
  114. }
  115. if (buffer[1] != nullptr)
  116. {
  117. delete[] buffer[1];
  118. buffer[1] = nullptr;
  119. }
  120. if (tmpbuf[0] != nullptr)
  121. {
  122. delete[] tmpbuf[0];
  123. tmpbuf[0] = nullptr;
  124. }
  125. if (tmpbuf[1] != nullptr)
  126. {
  127. delete[] tmpbuf[1];
  128. tmpbuf[1] = nullptr;
  129. }
  130. }
  131. // NOTE it is assumed that mutex is locked
  132. bool tryPutData(float* const out1,
  133. float* const out2,
  134. uint64_t framePos,
  135. const uint32_t frames,
  136. const bool loopingMode,
  137. const bool isOffline,
  138. bool& needsRead,
  139. uint64_t& needsReadFrame)
  140. {
  141. CARLA_SAFE_ASSERT_RETURN(numFrames != 0, false);
  142. CARLA_SAFE_ASSERT_RETURN(maxFrame != 0, false);
  143. if (framePos >= maxFrame)
  144. {
  145. if (loopingMode)
  146. framePos %= maxFrame;
  147. else
  148. return false;
  149. }
  150. uint64_t frameDiff;
  151. const uint32_t numFramesNearEnd = numFrames*3/4;
  152. if (framePos < startFrame)
  153. {
  154. if (startFrame + numFrames <= maxFrame)
  155. {
  156. needsRead = true;
  157. needsReadFrame = framePos;
  158. return false;
  159. }
  160. frameDiff = framePos + (maxFrame - startFrame);
  161. if (frameDiff + frames >= numFrames)
  162. {
  163. needsRead = true;
  164. needsReadFrame = framePos;
  165. return false;
  166. }
  167. carla_copyFloats(out1, buffer[0] + frameDiff, frames);
  168. carla_copyFloats(out2, buffer[1] + frameDiff, frames);
  169. }
  170. else
  171. {
  172. frameDiff = framePos - startFrame;
  173. if (frameDiff + frames >= numFrames)
  174. {
  175. needsRead = true;
  176. needsReadFrame = framePos;
  177. return false;
  178. }
  179. carla_copyFloats(out1, buffer[0] + frameDiff, frames);
  180. carla_copyFloats(out2, buffer[1] + frameDiff, frames);
  181. }
  182. if (frameDiff > numFramesNearEnd)
  183. {
  184. needsRead = true;
  185. needsReadFrame = framePos + (isOffline ? 0 : frames);
  186. }
  187. return true;
  188. }
  189. CARLA_DECLARE_NON_COPYABLE(AudioFilePool)
  190. };
  191. class AudioFileReader
  192. {
  193. public:
  194. AudioFileReader()
  195. : fEntireFileLoaded(false),
  196. fLoopingMode(true),
  197. fCurrentBitRate(0),
  198. fNeedsFrame(0),
  199. fNeedsRead(false),
  200. fFilePtr(nullptr),
  201. fFileNfo(),
  202. fPollTempData(nullptr),
  203. fPollTempSize(0),
  204. fResampleRatio(0.0),
  205. fResampleTempData(nullptr),
  206. fResampleTempSize(0),
  207. fPool(),
  208. fPoolMutex(),
  209. fPoolReadyToSwap(false),
  210. fResampler(),
  211. fReaderMutex()
  212. {
  213. ad_clear_nfo(&fFileNfo);
  214. }
  215. ~AudioFileReader()
  216. {
  217. cleanup();
  218. }
  219. void cleanup()
  220. {
  221. fPool.destroy();
  222. fCurrentBitRate = 0;
  223. fEntireFileLoaded = false;
  224. if (fFilePtr != nullptr)
  225. {
  226. ad_close(fFilePtr);
  227. fFilePtr = nullptr;
  228. }
  229. if (fPollTempData != nullptr)
  230. {
  231. delete[] fPollTempData;
  232. fPollTempData = nullptr;
  233. fPollTempSize = 0;
  234. }
  235. if (fResampleTempData != nullptr)
  236. {
  237. delete[] fResampleTempData;
  238. fResampleTempData = nullptr;
  239. fResampleTempSize = 0;
  240. }
  241. }
  242. void destroy()
  243. {
  244. const CarlaMutexLocker cml(fReaderMutex);
  245. fPool.destroy();
  246. fNeedsFrame = 0;
  247. fNeedsRead = false;
  248. }
  249. bool isEntireFileLoaded() const noexcept
  250. {
  251. return fEntireFileLoaded;
  252. }
  253. int getCurrentBitRate() const noexcept
  254. {
  255. return fCurrentBitRate;
  256. }
  257. uint32_t getMaxFrame() const noexcept
  258. {
  259. return fPool.maxFrame;
  260. }
  261. ADInfo getFileInfo() const noexcept
  262. {
  263. return fFileNfo;
  264. }
  265. void setLoopingMode(const bool on) noexcept
  266. {
  267. fLoopingMode = on;
  268. }
  269. void setNeedsRead(const uint64_t frame) noexcept
  270. {
  271. if (fEntireFileLoaded)
  272. return;
  273. fNeedsFrame = frame;
  274. fNeedsRead = true;
  275. }
  276. bool loadFilename(const char* const filename, const uint32_t sampleRate,
  277. const uint32_t previewDataSize, float* previewData)
  278. {
  279. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
  280. const CarlaMutexLocker cml(fReaderMutex);
  281. cleanup();
  282. ad_clear_nfo(&fFileNfo);
  283. // open new
  284. fFilePtr = ad_open(filename, &fFileNfo);
  285. if (fFilePtr == nullptr)
  286. return false;
  287. ad_dump_nfo(99, &fFileNfo);
  288. // Fix for misinformation using libsndfile
  289. if (fFileNfo.frames % fFileNfo.channels)
  290. --fFileNfo.frames;
  291. if (fFileNfo.frames <= 0)
  292. carla_stderr("L: filename \"%s\" has 0 frames", filename);
  293. if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
  294. {
  295. // valid
  296. const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
  297. const uint32_t maxPoolNumFrames = sampleRate * 30;
  298. const bool needsResample = fFileNfo.sample_rate != sampleRate;
  299. uint32_t maxFrame;
  300. if (needsResample)
  301. {
  302. if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32))
  303. {
  304. ad_clear_nfo(&fFileNfo);
  305. ad_close(fFilePtr);
  306. fFilePtr = nullptr;
  307. carla_stderr2("loadFilename error, resampler setup failed");
  308. return false;
  309. }
  310. fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
  311. maxFrame = static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5);
  312. }
  313. else
  314. {
  315. fResampler.clear();
  316. fResampleRatio = 0.0;
  317. maxFrame = fileNumFrames;
  318. }
  319. if (fileNumFrames <= maxPoolNumFrames || fFileNfo.can_seek == 0)
  320. {
  321. // entire file fits in a small pool, lets read it now
  322. const uint32_t poolNumFrames = needsResample
  323. ? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
  324. : fileNumFrames;
  325. fPool.create(poolNumFrames, maxFrame, false);
  326. readEntireFileIntoPool(needsResample);
  327. ad_close(fFilePtr);
  328. fFilePtr = nullptr;
  329. const float fileNumFramesF = static_cast<float>(fileNumFrames);
  330. const float previewDataSizeF = static_cast<float>(previewDataSize);
  331. for (uint i=0; i<previewDataSize; ++i)
  332. {
  333. const float stepF = static_cast<float>(i)/previewDataSizeF * fileNumFramesF;
  334. const uint step = carla_fixedValue(0U, fileNumFrames-1U, static_cast<uint>(stepF + 0.5f));
  335. previewData[i] = std::max(std::fabs(fPool.buffer[0][step]), std::fabs(fPool.buffer[1][step]));
  336. }
  337. }
  338. else
  339. {
  340. // file is too big for our audio pool, we need an extra buffer
  341. const uint32_t poolNumFrames = sampleRate * 5;
  342. const uint pollTempSize = poolNumFrames * fFileNfo.channels;
  343. uint resampleTempSize = 0;
  344. readFilePreview(previewDataSize, previewData);
  345. fPool.create(poolNumFrames, maxFrame, true);
  346. try {
  347. fPollTempData = new float[pollTempSize];
  348. } catch (...) {
  349. ad_clear_nfo(&fFileNfo);
  350. ad_close(fFilePtr);
  351. fFilePtr = nullptr;
  352. carla_stderr2("loadFilename error, out of memory");
  353. return false;
  354. }
  355. CARLA_MLOCK(fPollTempData, sizeof(float)*pollTempSize);
  356. if (needsResample)
  357. {
  358. resampleTempSize = static_cast<uint32_t>(static_cast<double>(poolNumFrames) * fResampleRatio + 0.5);
  359. resampleTempSize *= fFileNfo.channels;
  360. try {
  361. fResampleTempData = new float[resampleTempSize];
  362. } catch (...) {
  363. delete[] fPollTempData;
  364. fPollTempData = nullptr;
  365. ad_clear_nfo(&fFileNfo);
  366. ad_close(fFilePtr);
  367. fFilePtr = nullptr;
  368. carla_stderr2("loadFilename error, out of memory");
  369. return false;
  370. }
  371. CARLA_MLOCK(fResampleTempData, sizeof(float)*resampleTempSize);
  372. }
  373. fPollTempSize = pollTempSize;
  374. fResampleTempSize = resampleTempSize;
  375. }
  376. fNeedsRead = true;
  377. return true;
  378. }
  379. else
  380. {
  381. // invalid
  382. ad_clear_nfo(&fFileNfo);
  383. ad_close(fFilePtr);
  384. fFilePtr = nullptr;
  385. return false;
  386. }
  387. }
  388. void createSwapablePool(AudioFilePool& pool)
  389. {
  390. pool.create(fPool.numFrames, fPool.maxFrame, false);
  391. }
  392. void putAndSwapAllData(AudioFilePool& pool)
  393. {
  394. const water::GenericScopedLock<water::SpinLock> gsl1(fPool.mutex);
  395. const water::GenericScopedLock<water::SpinLock> gsl2(pool.mutex);
  396. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0,);
  397. CARLA_SAFE_ASSERT_RETURN(fPool.buffer[0] != nullptr,);
  398. CARLA_SAFE_ASSERT_RETURN(fPool.tmpbuf[0] == nullptr,);
  399. CARLA_SAFE_ASSERT_RETURN(pool.numFrames == 0,);
  400. CARLA_SAFE_ASSERT_RETURN(pool.buffer[0] == nullptr,);
  401. CARLA_SAFE_ASSERT_RETURN(pool.tmpbuf[0] == nullptr,);
  402. pool.startFrame = fPool.startFrame;
  403. pool.numFrames = fPool.numFrames;
  404. pool.buffer[0] = fPool.buffer[0];
  405. pool.buffer[1] = fPool.buffer[1];
  406. fPool.startFrame = 0;
  407. fPool.numFrames = 0;
  408. fPool.buffer[0] = nullptr;
  409. fPool.buffer[1] = nullptr;
  410. }
  411. bool tryPutData(AudioFilePool& pool,
  412. float* const out1,
  413. float* const out2,
  414. uint64_t framePos,
  415. const uint32_t frames,
  416. const bool loopMode,
  417. const bool isOffline,
  418. bool& needsIdleRequest)
  419. {
  420. _tryPoolSwap(pool);
  421. bool needsRead = false;
  422. uint64_t needsReadFrame;
  423. const bool ret = pool.tryPutData(out1, out2, framePos, frames, loopMode, isOffline, needsRead, needsReadFrame);
  424. if (needsRead)
  425. {
  426. needsIdleRequest = true;
  427. setNeedsRead(needsReadFrame);
  428. }
  429. #ifdef DEBUG_FILE_OPS
  430. if (! ret) {
  431. carla_stdout("tryPutData fail");
  432. }
  433. #endif
  434. return ret;
  435. }
  436. void readFilePreview(uint32_t previewDataSize, float* previewData)
  437. {
  438. carla_zeroFloats(previewData, previewDataSize);
  439. const uint fileNumFrames = static_cast<uint>(fFileNfo.frames);
  440. const float fileNumFramesF = static_cast<float>(fileNumFrames);
  441. const float previewDataSizeF = static_cast<float>(previewDataSize);
  442. const uint samplesPerRun = fFileNfo.channels;
  443. const uint maxSampleToRead = fileNumFrames - samplesPerRun;
  444. CARLA_SAFE_ASSERT_INT_RETURN(samplesPerRun == 1 || samplesPerRun == 2, samplesPerRun,);
  445. float tmp[2] = { 0.0f, 0.0f };
  446. if (samplesPerRun == 2)
  447. previewDataSize -= 1;
  448. for (uint i=0; i<previewDataSize; ++i)
  449. {
  450. const float posF = static_cast<float>(i)/previewDataSizeF * fileNumFramesF;
  451. const uint pos = carla_fixedValue(0U, maxSampleToRead, static_cast<uint>(posF));
  452. ad_seek(fFilePtr, pos);
  453. ad_read(fFilePtr, tmp, samplesPerRun);
  454. previewData[i] = std::max(std::fabs(tmp[0]), std::fabs(tmp[1]));
  455. }
  456. }
  457. void readEntireFileIntoPool(const bool needsResample)
  458. {
  459. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames > 0,);
  460. const uint numChannels = fFileNfo.channels;
  461. const uint fileNumFrames = static_cast<uint>(fFileNfo.frames);
  462. const uint bufferSize = fileNumFrames * numChannels;
  463. float* const buffer = (float*)std::calloc(bufferSize, sizeof(float));
  464. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  465. ad_seek(fFilePtr, 0);
  466. ssize_t rv = ad_read(fFilePtr, buffer, bufferSize);
  467. CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(bufferSize),
  468. static_cast<int>(rv),
  469. static_cast<int>(bufferSize),
  470. std::free(buffer));
  471. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  472. float* rbuffer;
  473. if (needsResample)
  474. {
  475. const uint rbufferSize = fPool.numFrames * numChannels;
  476. rbuffer = (float*)std::calloc(rbufferSize, sizeof(float));
  477. CARLA_SAFE_ASSERT_RETURN(rbuffer != nullptr, std::free(buffer););
  478. rv = static_cast<ssize_t>(rbufferSize);
  479. fResampler.inp_count = fileNumFrames;
  480. fResampler.out_count = fPool.numFrames;
  481. fResampler.inp_data = buffer;
  482. fResampler.out_data = rbuffer;
  483. fResampler.process();
  484. CARLA_SAFE_ASSERT_INT(fResampler.inp_count <= 2, fResampler.inp_count);
  485. }
  486. else
  487. {
  488. rbuffer = buffer;
  489. }
  490. {
  491. // lock, and put data asap
  492. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  493. if (numChannels == 1)
  494. {
  495. for (ssize_t i=0, j=0; j < rv; ++i, ++j)
  496. fPool.buffer[0][i] = fPool.buffer[1][i] = rbuffer[j];
  497. }
  498. else
  499. {
  500. for (ssize_t i=0, j=0; j < rv; ++j)
  501. {
  502. if (j % 2 == 0)
  503. {
  504. fPool.buffer[0][i] = rbuffer[j];
  505. }
  506. else
  507. {
  508. fPool.buffer[1][i] = rbuffer[j];
  509. ++i;
  510. }
  511. }
  512. }
  513. }
  514. if (rbuffer != buffer)
  515. std::free(rbuffer);
  516. std::free(buffer);
  517. fEntireFileLoaded = true;
  518. }
  519. void readPoll()
  520. {
  521. const CarlaMutexLocker cml(fReaderMutex);
  522. if (fFileNfo.channels == 0 || fFilePtr == nullptr)
  523. {
  524. carla_debug("R: no song loaded");
  525. fNeedsFrame = 0;
  526. fNeedsRead = false;
  527. return;
  528. }
  529. if (fPollTempData == nullptr)
  530. {
  531. carla_debug("R: nothing to poll");
  532. fNeedsFrame = 0;
  533. fNeedsRead = false;
  534. return;
  535. }
  536. const uint32_t maxFrame = fPool.maxFrame;
  537. uint64_t lastFrame = fNeedsFrame;
  538. int64_t readFrameCheck;
  539. if (lastFrame >= maxFrame)
  540. {
  541. if (fLoopingMode)
  542. {
  543. const uint64_t readFrameCheckLoop = lastFrame % maxFrame;
  544. CARLA_SAFE_ASSERT_RETURN(readFrameCheckLoop < INT32_MAX,);
  545. carla_debug("R: transport out of bounds for loop");
  546. readFrameCheck = static_cast<int64_t>(readFrameCheckLoop);
  547. }
  548. else
  549. {
  550. carla_debug("R: transport out of bounds");
  551. fNeedsFrame = 0;
  552. fNeedsRead = false;
  553. return;
  554. }
  555. }
  556. else
  557. {
  558. CARLA_SAFE_ASSERT_RETURN(lastFrame < INT32_MAX,);
  559. readFrameCheck = static_cast<int64_t>(lastFrame);
  560. }
  561. const int64_t readFrame = readFrameCheck;
  562. // temp data buffer
  563. carla_zeroFloats(fPollTempData, fPollTempSize);
  564. {
  565. #if 0
  566. const int32_t sampleRate = 44100;
  567. carla_debug("R: poll data - reading at frame %li, time %li:%02li, lastFrame %li",
  568. readFrame, readFrame/sampleRate/60, (readFrame/sampleRate) % 60, lastFrame);
  569. #endif
  570. const int64_t readFrameReal = carla_isNotZero(fResampleRatio)
  571. ? static_cast<int64_t>(static_cast<double>(readFrame) / fResampleRatio + 0.5)
  572. : readFrame;
  573. ad_seek(fFilePtr, readFrameReal);
  574. size_t i = 0;
  575. ssize_t j = 0;
  576. ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
  577. if (rv < 0)
  578. {
  579. carla_stderr("R: ad_read1 failed");
  580. fNeedsFrame = 0;
  581. fNeedsRead = false;
  582. return;
  583. }
  584. const size_t urv = static_cast<size_t>(rv);
  585. // see if we can read more
  586. if (readFrameReal + rv >= static_cast<ssize_t>(fFileNfo.frames) && urv < fPollTempSize)
  587. {
  588. #ifdef DEBUG_FILE_OPS
  589. carla_stdout("R: from start");
  590. #endif
  591. ad_seek(fFilePtr, 0);
  592. j = ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv);
  593. if (j < 0)
  594. {
  595. carla_stderr("R: ad_read2 failed");
  596. fNeedsFrame = 0;
  597. fNeedsRead = false;
  598. return;
  599. }
  600. rv += j;
  601. }
  602. #ifdef DEBUG_FILE_OPS
  603. carla_stdout("R: reading %li frames at frame %lu", rv, readFrameCheck);
  604. #endif
  605. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  606. // local copy
  607. const uint32_t poolNumFrames = fPool.numFrames;
  608. float* const pbuffer0 = fPool.tmpbuf[0];
  609. float* const pbuffer1 = fPool.tmpbuf[1];
  610. const float* tmpbuf = fPollTempData;
  611. // resample as needed
  612. if (fResampleTempSize != 0)
  613. {
  614. tmpbuf = fResampleTempData;
  615. fResampler.inp_count = static_cast<uint>(rv / fFileNfo.channels);
  616. fResampler.out_count = fResampleTempSize / fFileNfo.channels;
  617. fResampler.inp_data = fPollTempData;
  618. fResampler.out_data = fResampleTempData;
  619. fResampler.process();
  620. CARLA_ASSERT_INT(fResampler.inp_count <= 1, fResampler.inp_count);
  621. }
  622. j = 0;
  623. do {
  624. if (fFileNfo.channels == 1)
  625. {
  626. for (; i < poolNumFrames && j < rv; ++i, ++j)
  627. pbuffer0[i] = pbuffer1[i] = tmpbuf[j];
  628. }
  629. else
  630. {
  631. for (; i < poolNumFrames && j < rv; ++j)
  632. {
  633. if (j % 2 == 0)
  634. {
  635. pbuffer0[i] = tmpbuf[j];
  636. }
  637. else
  638. {
  639. pbuffer1[i] = tmpbuf[j];
  640. ++i;
  641. }
  642. }
  643. }
  644. if (i >= poolNumFrames)
  645. break;
  646. if (rv == fFileNfo.frames)
  647. {
  648. // full file read
  649. j = 0;
  650. #ifdef DEBUG_FILE_OPS
  651. carla_stdout("R: full file was read, filling buffers again");
  652. #endif
  653. }
  654. else
  655. {
  656. #ifdef DEBUG_FILE_OPS
  657. carla_stdout("read break, not enough space");
  658. #endif
  659. carla_zeroFloats(pbuffer0, poolNumFrames - i);
  660. carla_zeroFloats(pbuffer1, poolNumFrames - i);
  661. break;
  662. }
  663. } while (i < poolNumFrames);
  664. // lock, and put data asap
  665. const CarlaMutexLocker cmlp(fPoolMutex);
  666. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  667. std::memcpy(fPool.buffer[0], pbuffer0, sizeof(float)*poolNumFrames);
  668. std::memcpy(fPool.buffer[1], pbuffer1, sizeof(float)*poolNumFrames);
  669. fPool.startFrame = static_cast<uint64_t>(readFrame);
  670. fPoolReadyToSwap = true;
  671. #ifdef DEBUG_FILE_OPS
  672. carla_stdout("Reading done and internal pool is now full");
  673. #endif
  674. }
  675. fNeedsRead = false;
  676. }
  677. private:
  678. bool fEntireFileLoaded;
  679. bool fLoopingMode;
  680. int fCurrentBitRate;
  681. volatile uint64_t fNeedsFrame;
  682. volatile bool fNeedsRead;
  683. void* fFilePtr;
  684. ADInfo fFileNfo;
  685. float* fPollTempData;
  686. uint fPollTempSize;
  687. double fResampleRatio;
  688. float* fResampleTempData;
  689. uint fResampleTempSize;
  690. AudioFilePool fPool;
  691. CarlaMutex fPoolMutex;
  692. bool fPoolReadyToSwap;
  693. Resampler fResampler;
  694. CarlaMutex fReaderMutex;
  695. // try a pool data swap if possible and relevant
  696. // NOTE it is assumed that `pool` mutex is locked
  697. void _tryPoolSwap(AudioFilePool& pool)
  698. {
  699. uint32_t tmp_u32;
  700. uint64_t tmp_u64;
  701. float* tmp_fp;
  702. const CarlaMutexTryLocker cmtl(fPoolMutex);
  703. if (! cmtl.wasLocked())
  704. return;
  705. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  706. if (! fPoolReadyToSwap)
  707. return;
  708. tmp_u64 = pool.startFrame;
  709. pool.startFrame = fPool.startFrame;
  710. fPool.startFrame = tmp_u64;
  711. tmp_u32 = pool.numFrames;
  712. pool.numFrames = fPool.numFrames;
  713. fPool.numFrames = tmp_u32;
  714. tmp_fp = pool.buffer[0];
  715. pool.buffer[0] = fPool.buffer[0];
  716. fPool.buffer[0] = tmp_fp;
  717. tmp_fp = pool.buffer[1];
  718. pool.buffer[1] = fPool.buffer[1];
  719. fPool.buffer[1] = tmp_fp;
  720. fPoolReadyToSwap = false;
  721. #ifdef DEBUG_FILE_OPS
  722. carla_stdout("Pools have been swapped, internal one is now invalidated");
  723. #endif
  724. }
  725. CARLA_DECLARE_NON_COPYABLE(AudioFileReader)
  726. };
  727. #endif // AUDIO_BASE_HPP_INCLUDED