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.

874 lines
26KB

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