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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  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. ad_clear_nfo(&fFileNfo);
  213. }
  214. ~AudioFileReader()
  215. {
  216. cleanup();
  217. }
  218. void cleanup()
  219. {
  220. fPool.destroy();
  221. fCurrentBitRate = 0;
  222. fEntireFileLoaded = false;
  223. if (fFilePtr != nullptr)
  224. {
  225. ad_close(fFilePtr);
  226. fFilePtr = nullptr;
  227. }
  228. if (fPollTempData != nullptr)
  229. {
  230. delete[] fPollTempData;
  231. fPollTempData = nullptr;
  232. fPollTempSize = 0;
  233. }
  234. if (fResampleTempData != nullptr)
  235. {
  236. delete[] fResampleTempData;
  237. fResampleTempData = nullptr;
  238. fResampleTempSize = 0;
  239. }
  240. }
  241. void destroy()
  242. {
  243. const CarlaMutexLocker cml(fReaderMutex);
  244. fPool.destroy();
  245. fNeedsFrame = 0;
  246. fNeedsRead = false;
  247. }
  248. bool isEntireFileLoaded() const noexcept
  249. {
  250. return fEntireFileLoaded;
  251. }
  252. int getCurrentBitRate() const noexcept
  253. {
  254. return fCurrentBitRate;
  255. }
  256. uint32_t getMaxFrame() const noexcept
  257. {
  258. return fPool.maxFrame;
  259. }
  260. ADInfo getFileInfo() const noexcept
  261. {
  262. return fFileNfo;
  263. }
  264. void setLoopingMode(const bool on) noexcept
  265. {
  266. fLoopingMode = on;
  267. }
  268. void setNeedsRead(const uint64_t frame) noexcept
  269. {
  270. if (fEntireFileLoaded)
  271. return;
  272. fNeedsFrame = frame;
  273. fNeedsRead = true;
  274. }
  275. bool loadFilename(const char* const filename, const uint32_t sampleRate,
  276. const uint32_t previewDataSize, float* previewData)
  277. {
  278. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
  279. const CarlaMutexLocker cml(fReaderMutex);
  280. cleanup();
  281. ad_clear_nfo(&fFileNfo);
  282. // open new
  283. fFilePtr = ad_open(filename, &fFileNfo);
  284. if (fFilePtr == nullptr)
  285. return false;
  286. ad_dump_nfo(99, &fFileNfo);
  287. // Fix for misinformation using libsndfile
  288. if (fFileNfo.frames % fFileNfo.channels)
  289. --fFileNfo.frames;
  290. if (fFileNfo.frames <= 0)
  291. carla_stderr("L: filename \"%s\" has 0 frames", filename);
  292. if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
  293. {
  294. // valid
  295. const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
  296. const uint32_t maxPoolNumFrames = sampleRate * 30;
  297. const bool needsResample = fFileNfo.sample_rate != sampleRate;
  298. uint32_t maxFrame;
  299. if (needsResample)
  300. {
  301. if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32))
  302. {
  303. ad_clear_nfo(&fFileNfo);
  304. ad_close(fFilePtr);
  305. fFilePtr = nullptr;
  306. carla_stderr2("loadFilename error, resampler setup failed");
  307. return false;
  308. }
  309. fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
  310. maxFrame = static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5);
  311. }
  312. else
  313. {
  314. fResampler.clear();
  315. fResampleRatio = 0.0;
  316. maxFrame = fileNumFrames;
  317. }
  318. if (fileNumFrames <= maxPoolNumFrames || fFileNfo.can_seek == 0)
  319. {
  320. // entire file fits in a small pool, lets read it now
  321. const uint32_t poolNumFrames = needsResample
  322. ? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
  323. : fileNumFrames;
  324. fPool.create(poolNumFrames, maxFrame, false);
  325. readEntireFileIntoPool(needsResample);
  326. ad_close(fFilePtr);
  327. fFilePtr = nullptr;
  328. const float fileNumFramesF = static_cast<float>(fileNumFrames);
  329. const float previewDataSizeF = static_cast<float>(previewDataSize);
  330. for (uint i=0; i<previewDataSize; ++i)
  331. {
  332. const float stepF = static_cast<float>(i)/previewDataSizeF * fileNumFramesF;
  333. const uint step = carla_fixedValue(0U, fileNumFrames-1U, static_cast<uint>(stepF + 0.5f));
  334. previewData[i] = std::max(std::fabs(fPool.buffer[0][step]), std::fabs(fPool.buffer[1][step]));
  335. }
  336. }
  337. else
  338. {
  339. // file is too big for our audio pool, we need an extra buffer
  340. const uint32_t poolNumFrames = sampleRate * 5;
  341. const uint pollTempSize = poolNumFrames * fFileNfo.channels;
  342. uint resampleTempSize = 0;
  343. readFilePreview(previewDataSize, previewData);
  344. fPool.create(poolNumFrames, maxFrame, true);
  345. try {
  346. fPollTempData = new float[pollTempSize];
  347. } catch (...) {
  348. ad_clear_nfo(&fFileNfo);
  349. ad_close(fFilePtr);
  350. fFilePtr = nullptr;
  351. carla_stderr2("loadFilename error, out of memory");
  352. return false;
  353. }
  354. CARLA_MLOCK(fPollTempData, sizeof(float)*pollTempSize);
  355. if (needsResample)
  356. {
  357. resampleTempSize = static_cast<uint32_t>(static_cast<double>(poolNumFrames) * fResampleRatio + 0.5);
  358. resampleTempSize *= fFileNfo.channels;
  359. try {
  360. fResampleTempData = new float[resampleTempSize];
  361. } catch (...) {
  362. delete[] fPollTempData;
  363. fPollTempData = nullptr;
  364. ad_clear_nfo(&fFileNfo);
  365. ad_close(fFilePtr);
  366. fFilePtr = nullptr;
  367. carla_stderr2("loadFilename error, out of memory");
  368. return false;
  369. }
  370. CARLA_MLOCK(fResampleTempData, sizeof(float)*resampleTempSize);
  371. }
  372. fPollTempSize = pollTempSize;
  373. fResampleTempSize = resampleTempSize;
  374. }
  375. fNeedsRead = true;
  376. return true;
  377. }
  378. else
  379. {
  380. // invalid
  381. ad_clear_nfo(&fFileNfo);
  382. ad_close(fFilePtr);
  383. fFilePtr = nullptr;
  384. return false;
  385. }
  386. }
  387. void createSwapablePool(AudioFilePool& pool)
  388. {
  389. pool.create(fPool.numFrames, fPool.maxFrame, false);
  390. }
  391. void putAndSwapAllData(AudioFilePool& pool)
  392. {
  393. const water::GenericScopedLock<water::SpinLock> gsl1(fPool.mutex);
  394. const water::GenericScopedLock<water::SpinLock> gsl2(pool.mutex);
  395. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0,);
  396. CARLA_SAFE_ASSERT_RETURN(fPool.buffer[0] != nullptr,);
  397. CARLA_SAFE_ASSERT_RETURN(fPool.tmpbuf[0] == nullptr,);
  398. CARLA_SAFE_ASSERT_RETURN(pool.numFrames == 0,);
  399. CARLA_SAFE_ASSERT_RETURN(pool.buffer[0] == nullptr,);
  400. CARLA_SAFE_ASSERT_RETURN(pool.tmpbuf[0] == nullptr,);
  401. pool.startFrame = fPool.startFrame;
  402. pool.numFrames = fPool.numFrames;
  403. pool.buffer[0] = fPool.buffer[0];
  404. pool.buffer[1] = fPool.buffer[1];
  405. fPool.startFrame = 0;
  406. fPool.numFrames = 0;
  407. fPool.buffer[0] = nullptr;
  408. fPool.buffer[1] = nullptr;
  409. }
  410. bool tryPutData(AudioFilePool& pool,
  411. float* const out1,
  412. float* const out2,
  413. uint64_t framePos,
  414. const uint32_t frames,
  415. const bool loopMode,
  416. const bool isOffline,
  417. bool& needsIdleRequest)
  418. {
  419. _tryPoolSwap(pool);
  420. bool needsRead = false;
  421. uint64_t needsReadFrame;
  422. const bool ret = pool.tryPutData(out1, out2, framePos, frames, loopMode, isOffline, needsRead, needsReadFrame);
  423. if (needsRead)
  424. {
  425. needsIdleRequest = true;
  426. setNeedsRead(needsReadFrame);
  427. }
  428. #ifdef DEBUG_FILE_OPS
  429. if (! ret) {
  430. carla_stdout("tryPutData fail");
  431. }
  432. #endif
  433. return ret;
  434. }
  435. void readFilePreview(uint32_t previewDataSize, float* previewData)
  436. {
  437. carla_zeroFloats(previewData, previewDataSize);
  438. const uint fileNumFrames = static_cast<uint>(fFileNfo.frames);
  439. const float fileNumFramesF = static_cast<float>(fileNumFrames);
  440. const float previewDataSizeF = static_cast<float>(previewDataSize);
  441. const uint samplesPerRun = fFileNfo.channels;
  442. const uint maxSampleToRead = fileNumFrames - samplesPerRun;
  443. CARLA_SAFE_ASSERT_INT_RETURN(samplesPerRun == 1 || samplesPerRun == 2, samplesPerRun,);
  444. float tmp[2] = { 0.0f, 0.0f };
  445. if (samplesPerRun == 2)
  446. previewDataSize -= 1;
  447. for (uint i=0; i<previewDataSize; ++i)
  448. {
  449. const float posF = static_cast<float>(i)/previewDataSizeF * fileNumFramesF;
  450. const uint pos = carla_fixedValue(0U, maxSampleToRead, static_cast<uint>(posF));
  451. ad_seek(fFilePtr, pos);
  452. ad_read(fFilePtr, tmp, samplesPerRun);
  453. previewData[i] = std::max(std::fabs(tmp[0]), std::fabs(tmp[1]));
  454. }
  455. }
  456. void readEntireFileIntoPool(const bool needsResample)
  457. {
  458. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames > 0,);
  459. const uint numChannels = fFileNfo.channels;
  460. const uint fileNumFrames = static_cast<uint>(fFileNfo.frames);
  461. const uint bufferSize = fileNumFrames * numChannels;
  462. float* const buffer = (float*)std::calloc(bufferSize, sizeof(float));
  463. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  464. ad_seek(fFilePtr, 0);
  465. ssize_t rv = ad_read(fFilePtr, buffer, bufferSize);
  466. CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(bufferSize),
  467. static_cast<int>(rv),
  468. static_cast<int>(bufferSize),
  469. std::free(buffer));
  470. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  471. float* rbuffer;
  472. if (needsResample)
  473. {
  474. const uint rbufferSize = fPool.numFrames * numChannels;
  475. rbuffer = (float*)std::calloc(rbufferSize, sizeof(float));
  476. CARLA_SAFE_ASSERT_RETURN(rbuffer != nullptr, std::free(buffer););
  477. rv = static_cast<ssize_t>(rbufferSize);
  478. fResampler.inp_count = fileNumFrames;
  479. fResampler.out_count = fPool.numFrames;
  480. fResampler.inp_data = buffer;
  481. fResampler.out_data = rbuffer;
  482. fResampler.process();
  483. CARLA_SAFE_ASSERT_INT(fResampler.inp_count <= 2, fResampler.inp_count);
  484. }
  485. else
  486. {
  487. rbuffer = buffer;
  488. }
  489. {
  490. // lock, and put data asap
  491. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  492. if (numChannels == 1)
  493. {
  494. for (ssize_t i=0, j=0; j < rv; ++i, ++j)
  495. fPool.buffer[0][i] = fPool.buffer[1][i] = rbuffer[j];
  496. }
  497. else
  498. {
  499. for (ssize_t i=0, j=0; j < rv; ++j)
  500. {
  501. if (j % 2 == 0)
  502. {
  503. fPool.buffer[0][i] = rbuffer[j];
  504. }
  505. else
  506. {
  507. fPool.buffer[1][i] = rbuffer[j];
  508. ++i;
  509. }
  510. }
  511. }
  512. }
  513. if (rbuffer != buffer)
  514. std::free(rbuffer);
  515. std::free(buffer);
  516. fEntireFileLoaded = true;
  517. }
  518. void readPoll()
  519. {
  520. const CarlaMutexLocker cml(fReaderMutex);
  521. if (fFileNfo.channels == 0 || fFilePtr == nullptr)
  522. {
  523. carla_debug("R: no song loaded");
  524. fNeedsFrame = 0;
  525. fNeedsRead = false;
  526. return;
  527. }
  528. if (fPollTempData == nullptr)
  529. {
  530. carla_debug("R: nothing to poll");
  531. fNeedsFrame = 0;
  532. fNeedsRead = false;
  533. return;
  534. }
  535. const uint32_t maxFrame = fPool.maxFrame;
  536. uint64_t lastFrame = fNeedsFrame;
  537. int64_t readFrameCheck;
  538. if (lastFrame >= maxFrame)
  539. {
  540. if (fLoopingMode)
  541. {
  542. const uint64_t readFrameCheckLoop = lastFrame % maxFrame;
  543. CARLA_SAFE_ASSERT_RETURN(readFrameCheckLoop < INT32_MAX,);
  544. carla_debug("R: transport out of bounds for loop");
  545. readFrameCheck = static_cast<int64_t>(readFrameCheckLoop);
  546. }
  547. else
  548. {
  549. carla_debug("R: transport out of bounds");
  550. fNeedsFrame = 0;
  551. fNeedsRead = false;
  552. return;
  553. }
  554. }
  555. else
  556. {
  557. CARLA_SAFE_ASSERT_RETURN(lastFrame < INT32_MAX,);
  558. readFrameCheck = static_cast<int64_t>(lastFrame);
  559. }
  560. const int64_t readFrame = readFrameCheck;
  561. // temp data buffer
  562. carla_zeroFloats(fPollTempData, fPollTempSize);
  563. {
  564. #if 0
  565. const int32_t sampleRate = 44100;
  566. carla_debug("R: poll data - reading at frame %li, time %li:%02li, lastFrame %li",
  567. readFrame, readFrame/sampleRate/60, (readFrame/sampleRate) % 60, lastFrame);
  568. #endif
  569. const int64_t readFrameReal = carla_isNotZero(fResampleRatio)
  570. ? static_cast<int64_t>(static_cast<double>(readFrame) / fResampleRatio + 0.5)
  571. : readFrame;
  572. ad_seek(fFilePtr, readFrameReal);
  573. size_t i = 0;
  574. ssize_t j = 0;
  575. ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
  576. if (rv < 0)
  577. {
  578. carla_stderr("R: ad_read1 failed");
  579. fNeedsFrame = 0;
  580. fNeedsRead = false;
  581. return;
  582. }
  583. const size_t urv = static_cast<size_t>(rv);
  584. // see if we can read more
  585. if (readFrameReal + rv >= static_cast<ssize_t>(fFileNfo.frames) && urv < fPollTempSize)
  586. {
  587. #ifdef DEBUG_FILE_OPS
  588. carla_stdout("R: from start");
  589. #endif
  590. ad_seek(fFilePtr, 0);
  591. j = ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv);
  592. if (j < 0)
  593. {
  594. carla_stderr("R: ad_read2 failed");
  595. fNeedsFrame = 0;
  596. fNeedsRead = false;
  597. return;
  598. }
  599. rv += j;
  600. }
  601. #ifdef DEBUG_FILE_OPS
  602. carla_stdout("R: reading %li frames at frame %lu", rv, readFrameCheck);
  603. #endif
  604. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  605. // local copy
  606. const uint32_t poolNumFrames = fPool.numFrames;
  607. float* const pbuffer0 = fPool.tmpbuf[0];
  608. float* const pbuffer1 = fPool.tmpbuf[1];
  609. const float* tmpbuf = fPollTempData;
  610. // resample as needed
  611. if (fResampleTempSize != 0)
  612. {
  613. tmpbuf = fResampleTempData;
  614. fResampler.inp_count = static_cast<uint>(rv / fFileNfo.channels);
  615. fResampler.out_count = fResampleTempSize / fFileNfo.channels;
  616. fResampler.inp_data = fPollTempData;
  617. fResampler.out_data = fResampleTempData;
  618. fResampler.process();
  619. CARLA_ASSERT_INT(fResampler.inp_count <= 1, fResampler.inp_count);
  620. }
  621. j = 0;
  622. do {
  623. if (fFileNfo.channels == 1)
  624. {
  625. for (; i < poolNumFrames && j < rv; ++i, ++j)
  626. pbuffer0[i] = pbuffer1[i] = tmpbuf[j];
  627. }
  628. else
  629. {
  630. for (; i < poolNumFrames && j < rv; ++j)
  631. {
  632. if (j % 2 == 0)
  633. {
  634. pbuffer0[i] = tmpbuf[j];
  635. }
  636. else
  637. {
  638. pbuffer1[i] = tmpbuf[j];
  639. ++i;
  640. }
  641. }
  642. }
  643. if (i >= poolNumFrames)
  644. break;
  645. if (rv == fFileNfo.frames)
  646. {
  647. // full file read
  648. j = 0;
  649. #ifdef DEBUG_FILE_OPS
  650. carla_stdout("R: full file was read, filling buffers again");
  651. #endif
  652. }
  653. else
  654. {
  655. #ifdef DEBUG_FILE_OPS
  656. carla_stdout("read break, not enough space");
  657. #endif
  658. carla_zeroFloats(pbuffer0, poolNumFrames - i);
  659. carla_zeroFloats(pbuffer1, poolNumFrames - i);
  660. break;
  661. }
  662. } while (i < poolNumFrames);
  663. // lock, and put data asap
  664. const CarlaMutexLocker cmlp(fPoolMutex);
  665. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  666. std::memcpy(fPool.buffer[0], pbuffer0, sizeof(float)*poolNumFrames);
  667. std::memcpy(fPool.buffer[1], pbuffer1, sizeof(float)*poolNumFrames);
  668. fPool.startFrame = static_cast<uint64_t>(readFrame);
  669. fPoolReadyToSwap = true;
  670. #ifdef DEBUG_FILE_OPS
  671. carla_stdout("Reading done and internal pool is now full");
  672. #endif
  673. }
  674. fNeedsRead = false;
  675. }
  676. private:
  677. bool fEntireFileLoaded;
  678. bool fLoopingMode;
  679. int fCurrentBitRate;
  680. volatile uint64_t fNeedsFrame;
  681. volatile bool fNeedsRead;
  682. void* fFilePtr;
  683. ADInfo fFileNfo;
  684. float* fPollTempData;
  685. uint fPollTempSize;
  686. double fResampleRatio;
  687. float* fResampleTempData;
  688. uint fResampleTempSize;
  689. AudioFilePool fPool;
  690. CarlaMutex fPoolMutex;
  691. bool fPoolReadyToSwap;
  692. Resampler fResampler;
  693. CarlaMutex fReaderMutex;
  694. // try a pool data swap if possible and relevant
  695. // NOTE it is assumed that `pool` mutex is locked
  696. void _tryPoolSwap(AudioFilePool& pool)
  697. {
  698. uint32_t tmp_u32;
  699. uint64_t tmp_u64;
  700. float* tmp_fp;
  701. const CarlaMutexTryLocker cmtl(fPoolMutex);
  702. if (! cmtl.wasLocked())
  703. return;
  704. const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
  705. if (! fPoolReadyToSwap)
  706. return;
  707. tmp_u64 = pool.startFrame;
  708. pool.startFrame = fPool.startFrame;
  709. fPool.startFrame = tmp_u64;
  710. tmp_u32 = pool.numFrames;
  711. pool.numFrames = fPool.numFrames;
  712. fPool.numFrames = tmp_u32;
  713. tmp_fp = pool.buffer[0];
  714. pool.buffer[0] = fPool.buffer[0];
  715. fPool.buffer[0] = tmp_fp;
  716. tmp_fp = pool.buffer[1];
  717. pool.buffer[1] = fPool.buffer[1];
  718. fPool.buffer[1] = tmp_fp;
  719. fPoolReadyToSwap = false;
  720. #ifdef DEBUG_FILE_OPS
  721. carla_stdout("Pools have been swapped, internal one is now invalidated");
  722. #endif
  723. }
  724. CARLA_DECLARE_NON_COPY_STRUCT(AudioFileReader)
  725. };
  726. #endif // AUDIO_BASE_HPP_INCLUDED