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.

602 lines
15KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2019 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 "zita-resampler/resampler.h"
  25. typedef struct adinfo ADInfo;
  26. struct AudioFilePool {
  27. float* buffer[2];
  28. uint32_t numFrames;
  29. volatile uint64_t startFrame;
  30. #ifdef CARLA_PROPER_CPP11_SUPPORT
  31. AudioFilePool() noexcept
  32. : buffer{nullptr},
  33. numFrames(0),
  34. startFrame(0) {}
  35. #else
  36. AudioFilePool() noexcept
  37. : numFrames(0),
  38. startFrame(0)
  39. {
  40. buffer[0] = buffer[1] = nullptr;
  41. }
  42. #endif
  43. ~AudioFilePool()
  44. {
  45. destroy();
  46. }
  47. void create(const uint32_t desiredNumFrames)
  48. {
  49. CARLA_ASSERT(buffer[0] == nullptr);
  50. CARLA_ASSERT(buffer[1] == nullptr);
  51. CARLA_ASSERT(startFrame == 0);
  52. CARLA_ASSERT(numFrames == 0);
  53. numFrames = desiredNumFrames;
  54. buffer[0] = new float[numFrames];
  55. buffer[1] = new float[numFrames];
  56. reset();
  57. }
  58. void destroy() noexcept
  59. {
  60. if (buffer[0] != nullptr)
  61. {
  62. delete[] buffer[0];
  63. buffer[0] = nullptr;
  64. }
  65. if (buffer[1] != nullptr)
  66. {
  67. delete[] buffer[1];
  68. buffer[1] = nullptr;
  69. }
  70. startFrame = 0;
  71. numFrames = 0;
  72. }
  73. void reset() noexcept
  74. {
  75. startFrame = 0;
  76. if (numFrames != 0)
  77. {
  78. carla_zeroFloats(buffer[0], numFrames);
  79. carla_zeroFloats(buffer[1], numFrames);
  80. }
  81. }
  82. CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool)
  83. };
  84. class AudioFileThread : public CarlaThread
  85. {
  86. public:
  87. AudioFileThread()
  88. : CarlaThread("AudioFileThread"),
  89. fEntireFileLoaded(false),
  90. fLoopingMode(true),
  91. fNeedsFrame(0),
  92. fNeedsRead(false),
  93. fQuitNow(true),
  94. fFilePtr(nullptr),
  95. fFileNfo(),
  96. fNumFileFrames(0),
  97. fPollTempData(nullptr),
  98. fPollTempSize(0),
  99. fPool(),
  100. fMutex(),
  101. fSignal(),
  102. fResampler()
  103. {
  104. static bool adInitiated = false;
  105. if (! adInitiated)
  106. {
  107. ad_init();
  108. adInitiated = true;
  109. }
  110. ad_clear_nfo(&fFileNfo);
  111. }
  112. ~AudioFileThread() override
  113. {
  114. CARLA_ASSERT(fQuitNow);
  115. CARLA_ASSERT(! isThreadRunning());
  116. cleanup();
  117. }
  118. void cleanup()
  119. {
  120. fEntireFileLoaded = false;
  121. if (fFilePtr != nullptr)
  122. {
  123. ad_close(fFilePtr);
  124. fFilePtr = nullptr;
  125. }
  126. if (fPollTempData != nullptr)
  127. {
  128. delete[] fPollTempData;
  129. fPollTempData = nullptr;
  130. fPollTempSize = 0;
  131. }
  132. fPool.destroy();
  133. }
  134. void startNow()
  135. {
  136. if (fPollTempData == nullptr)
  137. return;
  138. fNeedsFrame = 0;
  139. fNeedsRead = false;
  140. fQuitNow = false;
  141. startThread();
  142. }
  143. void stopNow()
  144. {
  145. fNeedsFrame = 0;
  146. fNeedsRead = false;
  147. fQuitNow = true;
  148. fSignal.signal();
  149. stopThread(1000);
  150. const CarlaMutexLocker cml(fMutex);
  151. fPool.reset();
  152. }
  153. bool isEntireFileLoaded() const noexcept
  154. {
  155. return fEntireFileLoaded;
  156. }
  157. uint32_t getMaxFrame() const noexcept
  158. {
  159. return fNumFileFrames;
  160. }
  161. uint64_t getPoolStartFrame() const noexcept
  162. {
  163. return fPool.startFrame;
  164. }
  165. uint32_t getPoolNumFrames() const noexcept
  166. {
  167. return fPool.numFrames;
  168. }
  169. void setLoopingMode(const bool on) noexcept
  170. {
  171. fLoopingMode = on;
  172. }
  173. void setNeedsRead(const uint64_t frame) noexcept
  174. {
  175. if (fEntireFileLoaded)
  176. return;
  177. fNeedsFrame = frame;
  178. fNeedsRead = true;
  179. fSignal.signal();
  180. }
  181. bool loadFilename(const char* const filename, const uint32_t sampleRate)
  182. {
  183. CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(), false);
  184. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
  185. cleanup();
  186. ad_clear_nfo(&fFileNfo);
  187. // open new
  188. fFilePtr = ad_open(filename, &fFileNfo);
  189. if (fFilePtr == nullptr)
  190. return false;
  191. ad_dump_nfo(99, &fFileNfo);
  192. // Fix for misinformation using libsndfile
  193. if (fFileNfo.frames % fFileNfo.channels)
  194. --fFileNfo.frames;
  195. if (fFileNfo.frames <= 0)
  196. carla_stderr("L: filename \"%s\" has 0 frames", filename);
  197. if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
  198. {
  199. // valid
  200. const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
  201. const uint32_t poolNumFrames = sampleRate * 5;
  202. if (fileNumFrames <= poolNumFrames)
  203. {
  204. // entire file fits in a small pool, lets read it now
  205. fPool.create(fileNumFrames);
  206. readEntireFileIntoPool();
  207. ad_close(fFilePtr);
  208. fFilePtr = nullptr;
  209. }
  210. else
  211. {
  212. // file is too big for our audio pool, we need an extra buffer
  213. fPool.create(poolNumFrames);
  214. const size_t pollTempSize = poolNumFrames * fFileNfo.channels;
  215. try {
  216. fPollTempData = new float[pollTempSize];
  217. } catch (...) {
  218. ad_close(fFilePtr);
  219. fFilePtr = nullptr;
  220. return false;
  221. }
  222. fPollTempSize = pollTempSize;
  223. }
  224. fNumFileFrames = fileNumFrames;
  225. readPoll();
  226. return true;
  227. }
  228. else
  229. {
  230. // invalid
  231. ad_clear_nfo(&fFileNfo);
  232. ad_close(fFilePtr);
  233. fFilePtr = nullptr;
  234. return false;
  235. }
  236. }
  237. void putAllData(AudioFilePool& pool)
  238. {
  239. CARLA_SAFE_ASSERT_RETURN(pool.numFrames == fPool.numFrames,);
  240. const CarlaMutexLocker cml(fMutex);
  241. pool.startFrame = fPool.startFrame;
  242. carla_copyFloats(pool.buffer[0], fPool.buffer[0], fPool.numFrames);
  243. carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.numFrames);
  244. }
  245. bool tryPutData(float* const out1, float* const out2, uint64_t framePos, const uint32_t frames)
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0, false);
  248. if (framePos >= fNumFileFrames)
  249. {
  250. if (fLoopingMode)
  251. framePos %= fNumFileFrames;
  252. else
  253. return false;
  254. }
  255. uint64_t frameDiff;
  256. const uint64_t numFramesNearEnd = fPool.numFrames*3/4;
  257. #if 1
  258. const CarlaMutexLocker cml(fMutex);
  259. #else
  260. const CarlaMutexTryLocker cmtl(fMutex);
  261. if (! cmtl.wasLocked())
  262. {
  263. for (int i=0; i<5; ++i)
  264. {
  265. pthread_yield();
  266. if (cmtl.tryAgain())
  267. break;
  268. if (i == 4)
  269. return false;
  270. }
  271. }
  272. #endif
  273. if (framePos < fPool.startFrame)
  274. {
  275. if (fPool.startFrame + fPool.numFrames <= fNumFileFrames)
  276. {
  277. setNeedsRead(framePos);
  278. return false;
  279. }
  280. frameDiff = framePos + (fNumFileFrames - fPool.startFrame);
  281. if (frameDiff + frames >= fPool.numFrames)
  282. {
  283. setNeedsRead(framePos);
  284. return false;
  285. }
  286. carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames);
  287. carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames);
  288. }
  289. else
  290. {
  291. frameDiff = framePos - fPool.startFrame;
  292. if (frameDiff + frames >= fPool.numFrames)
  293. {
  294. setNeedsRead(framePos);
  295. return false;
  296. }
  297. carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames);
  298. carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames);
  299. }
  300. if (frameDiff > numFramesNearEnd)
  301. setNeedsRead(framePos + frames);
  302. return true;
  303. }
  304. void readEntireFileIntoPool()
  305. {
  306. CARLA_SAFE_ASSERT_RETURN(fPool.numFrames > 0,);
  307. const uint numChannels = fFileNfo.channels;
  308. const size_t bufferSize = fPool.numFrames * numChannels;
  309. float* const buffer = (float*)std::malloc(bufferSize*sizeof(float));
  310. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  311. carla_zeroFloats(buffer, bufferSize);
  312. ad_seek(fFilePtr, 0);
  313. ssize_t rv = ad_read(fFilePtr, buffer, bufferSize);
  314. CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(bufferSize),
  315. static_cast<int>(rv),
  316. static_cast<int>(bufferSize),
  317. std::free(buffer));
  318. {
  319. // lock, and put data asap
  320. const CarlaMutexLocker cml(fMutex);
  321. for (ssize_t i=0, j=0; j < rv; ++j)
  322. {
  323. if (numChannels == 1)
  324. {
  325. fPool.buffer[0][i] = buffer[j];
  326. fPool.buffer[1][i] = buffer[j];
  327. ++i;
  328. }
  329. else
  330. {
  331. if (j % 2 == 0)
  332. {
  333. fPool.buffer[0][i] = buffer[j];
  334. }
  335. else
  336. {
  337. fPool.buffer[1][i] = buffer[j];
  338. ++i;
  339. }
  340. }
  341. }
  342. }
  343. std::free(buffer);
  344. fEntireFileLoaded = true;
  345. }
  346. void readPoll()
  347. {
  348. if (fNumFileFrames == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
  349. {
  350. carla_debug("R: no song loaded");
  351. fNeedsFrame = 0;
  352. fNeedsRead = false;
  353. return;
  354. }
  355. if (fPollTempData == nullptr)
  356. {
  357. carla_debug("R: nothing to poll");
  358. fNeedsFrame = 0;
  359. fNeedsRead = false;
  360. return;
  361. }
  362. uint64_t lastFrame = fNeedsFrame;
  363. int64_t readFrameCheck;
  364. if (lastFrame >= fNumFileFrames)
  365. {
  366. if (fLoopingMode)
  367. {
  368. const uint64_t readFrameCheckLoop = lastFrame % fNumFileFrames;
  369. CARLA_SAFE_ASSERT_RETURN(readFrameCheckLoop < INT32_MAX,);
  370. carla_debug("R: transport out of bounds for loop");
  371. readFrameCheck = static_cast<int64_t>(readFrameCheckLoop);
  372. }
  373. else
  374. {
  375. carla_debug("R: transport out of bounds");
  376. fNeedsFrame = 0;
  377. fNeedsRead = false;
  378. return;
  379. }
  380. }
  381. else
  382. {
  383. CARLA_SAFE_ASSERT_RETURN(lastFrame < INT32_MAX,);
  384. readFrameCheck = static_cast<int64_t>(lastFrame);
  385. }
  386. const int64_t readFrame = readFrameCheck;
  387. // temp data buffer
  388. carla_zeroFloats(fPollTempData, fPollTempSize);
  389. {
  390. #if 0
  391. const int32_t sampleRate = 44100;
  392. carla_debug("R: poll data - reading at frame %li, time %li:%02li, lastFrame %li",
  393. readFrame, readFrame/sampleRate/60, (readFrame/sampleRate) % 60, lastFrame);
  394. #endif
  395. ad_seek(fFilePtr, readFrame);
  396. size_t i = 0;
  397. ssize_t j = 0;
  398. ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
  399. if (rv < 0)
  400. {
  401. carla_stderr("R: ad_read failed");
  402. fNeedsFrame = 0;
  403. fNeedsRead = false;
  404. return;
  405. }
  406. const size_t urv = static_cast<size_t>(rv);
  407. // see if we can read more
  408. if (readFrame + rv >= static_cast<ssize_t>(fFileNfo.frames) && urv < fPollTempSize)
  409. {
  410. carla_debug("R: from start");
  411. ad_seek(fFilePtr, 0);
  412. rv += ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv);
  413. }
  414. carla_debug("R: reading %li frames at frame %lu", rv, readFrameCheck);
  415. // local copy
  416. const uint32_t poolNumFrame = fPool.numFrames;
  417. const int64_t fileFrames = fFileNfo.frames;
  418. const bool isMonoFile = fFileNfo.channels == 1;
  419. float* const pbuffer0 = fPool.buffer[0];
  420. float* const pbuffer1 = fPool.buffer[1];
  421. const float* const tmpbuf = fPollTempData;
  422. // lock, and put data asap
  423. const CarlaMutexLocker cml(fMutex);
  424. do {
  425. for (; i < poolNumFrame && j < rv; ++j)
  426. {
  427. if (isMonoFile)
  428. {
  429. pbuffer0[i] = pbuffer1[i] = tmpbuf[j];
  430. i++;
  431. }
  432. else
  433. {
  434. if (j % 2 == 0)
  435. {
  436. pbuffer0[i] = tmpbuf[j];
  437. }
  438. else
  439. {
  440. pbuffer1[i] = tmpbuf[j];
  441. ++i;
  442. }
  443. }
  444. }
  445. if (i >= poolNumFrame) {
  446. break;
  447. }
  448. if (rv == fileFrames)
  449. {
  450. // full file read
  451. j = 0;
  452. carla_debug("R: full file was read, filling buffers again");
  453. }
  454. else
  455. {
  456. carla_debug("read break, not enough space");
  457. carla_zeroFloats(pbuffer0, poolNumFrame - i);
  458. carla_zeroFloats(pbuffer1, poolNumFrame - i);
  459. break;
  460. }
  461. } while (i < poolNumFrame);
  462. fPool.startFrame = static_cast<uint64_t>(readFrame);
  463. }
  464. fNeedsRead = false;
  465. }
  466. protected:
  467. void run() override
  468. {
  469. while (! fQuitNow)
  470. {
  471. if (fNeedsRead)
  472. readPoll();
  473. if (fQuitNow)
  474. break;
  475. fSignal.wait();
  476. }
  477. }
  478. private:
  479. bool fEntireFileLoaded;
  480. bool fLoopingMode;
  481. volatile uint64_t fNeedsFrame;
  482. volatile bool fNeedsRead;
  483. volatile bool fQuitNow;
  484. void* fFilePtr;
  485. ADInfo fFileNfo;
  486. uint32_t fNumFileFrames;
  487. float* fPollTempData;
  488. size_t fPollTempSize;
  489. AudioFilePool fPool;
  490. CarlaMutex fMutex;
  491. CarlaSignal fSignal;
  492. Resampler fResampler;
  493. CARLA_DECLARE_NON_COPY_STRUCT(AudioFileThread)
  494. };
  495. #endif // AUDIO_BASE_HPP_INCLUDED