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.

429 lines
10KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2018 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. typedef struct adinfo ADInfo;
  25. struct AudioFilePool {
  26. float* buffer[2];
  27. uint32_t sampleRate;
  28. uint32_t startFrame;
  29. uint32_t size;
  30. #ifdef CARLA_PROPER_CPP11_SUPPORT
  31. AudioFilePool()
  32. : buffer{nullptr},
  33. sampleRate(0),
  34. startFrame(0),
  35. size(0) {}
  36. #else
  37. AudioFilePool()
  38. : sampleRate(0),
  39. startFrame(0),
  40. size(0)
  41. {
  42. buffer[0] = buffer[1] = nullptr;
  43. }
  44. #endif
  45. ~AudioFilePool()
  46. {
  47. CARLA_ASSERT(buffer[0] == nullptr);
  48. CARLA_ASSERT(buffer[1] == nullptr);
  49. CARLA_ASSERT(startFrame == 0);
  50. CARLA_ASSERT(size == 0);
  51. }
  52. void create(const uint32_t srate)
  53. {
  54. CARLA_ASSERT(buffer[0] == nullptr);
  55. CARLA_ASSERT(buffer[1] == nullptr);
  56. CARLA_ASSERT(startFrame == 0);
  57. CARLA_ASSERT(size == 0);
  58. size = srate * 8;
  59. sampleRate = srate;
  60. buffer[0] = new float[size];
  61. buffer[1] = new float[size];
  62. reset();
  63. }
  64. void destroy()
  65. {
  66. CARLA_ASSERT(buffer[0] != nullptr);
  67. CARLA_ASSERT(buffer[1] != nullptr);
  68. CARLA_ASSERT(size != 0);
  69. if (buffer[0] != nullptr)
  70. {
  71. delete[] buffer[0];
  72. buffer[0] = nullptr;
  73. }
  74. if (buffer[1] != nullptr)
  75. {
  76. delete[] buffer[1];
  77. buffer[1] = nullptr;
  78. }
  79. startFrame = 0;
  80. size = 0;
  81. }
  82. void reset()
  83. {
  84. startFrame = 0;
  85. CARLA_SAFE_ASSERT_RETURN(size != 0,);
  86. carla_zeroFloats(buffer[0], size);
  87. carla_zeroFloats(buffer[1], size);
  88. }
  89. };
  90. class AbstractAudioPlayer
  91. {
  92. public:
  93. virtual ~AbstractAudioPlayer() {}
  94. virtual uint32_t getLastFrame() const = 0;
  95. };
  96. class AudioFileThread : public CarlaThread
  97. {
  98. public:
  99. AudioFileThread(AbstractAudioPlayer* const player, const double sampleRate)
  100. : CarlaThread("AudioFileThread"),
  101. kPlayer(player),
  102. fLoopingMode(true),
  103. fNeedsRead(false),
  104. fQuitNow(true),
  105. fFilePtr(nullptr),
  106. fMaxPlayerFrame(0),
  107. fPollTempData(nullptr),
  108. fPollTempSize(0)
  109. {
  110. CARLA_ASSERT(kPlayer != nullptr);
  111. static bool adInitiated = false;
  112. if (! adInitiated)
  113. {
  114. ad_init();
  115. adInitiated = true;
  116. }
  117. ad_clear_nfo(&fFileNfo);
  118. fPool.create(sampleRate);
  119. }
  120. ~AudioFileThread() override
  121. {
  122. CARLA_ASSERT(fQuitNow);
  123. CARLA_ASSERT(! isThreadRunning());
  124. if (fFilePtr != nullptr)
  125. {
  126. ad_close(fFilePtr);
  127. fFilePtr = nullptr;
  128. }
  129. if (fPollTempData != nullptr)
  130. {
  131. delete[] fPollTempData;
  132. fPollTempData = nullptr;
  133. fPollTempSize = 0;
  134. }
  135. fPool.destroy();
  136. }
  137. void startNow()
  138. {
  139. fNeedsRead = true;
  140. fQuitNow = false;
  141. startThread();
  142. }
  143. void stopNow()
  144. {
  145. fNeedsRead = false;
  146. fQuitNow = true;
  147. stopThread(1000);
  148. const CarlaMutexLocker cml(fMutex);
  149. fPool.reset();
  150. }
  151. uint32_t getMaxFrame() const noexcept
  152. {
  153. return fMaxPlayerFrame;
  154. }
  155. void setLoopingMode(const bool on) noexcept
  156. {
  157. fLoopingMode = on;
  158. }
  159. void setNeedsRead() noexcept
  160. {
  161. fNeedsRead = true;
  162. }
  163. bool loadFilename(const char* const filename)
  164. {
  165. CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(), false);
  166. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
  167. fPool.startFrame = 0;
  168. // clear old data
  169. if (fFilePtr != nullptr)
  170. {
  171. ad_close(fFilePtr);
  172. fFilePtr = nullptr;
  173. }
  174. if (fPollTempData != nullptr)
  175. {
  176. delete[] fPollTempData;
  177. fPollTempData = nullptr;
  178. fPollTempSize = 0;
  179. fMaxPlayerFrame = 0;
  180. }
  181. ad_clear_nfo(&fFileNfo);
  182. // open new
  183. fFilePtr = ad_open(filename, &fFileNfo);
  184. if (fFilePtr == nullptr)
  185. return false;
  186. ad_dump_nfo(99, &fFileNfo);
  187. // Fix for misinformation using libsndfile
  188. if (fFileNfo.frames % fFileNfo.channels)
  189. --fFileNfo.frames;
  190. if (fFileNfo.frames <= 0)
  191. carla_stderr("L: filename \"%s\" has 0 frames", filename);
  192. if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
  193. {
  194. // valid
  195. const size_t pollTempSize = std::min(static_cast<uint>(fFileNfo.frames),
  196. fPool.size * fFileNfo.channels);
  197. try {
  198. fPollTempData = new float[pollTempSize];
  199. } catch (...) {
  200. ad_close(fFilePtr);
  201. fFilePtr = nullptr;
  202. return false;
  203. }
  204. fMaxPlayerFrame = fFileNfo.frames/fFileNfo.channels;
  205. fPollTempSize = pollTempSize;
  206. readPoll();
  207. return true;
  208. }
  209. else
  210. {
  211. // invalid
  212. ad_clear_nfo(&fFileNfo);
  213. ad_close(fFilePtr);
  214. fFilePtr = nullptr;
  215. return false;
  216. }
  217. }
  218. void tryPutData(AudioFilePool& pool)
  219. {
  220. CARLA_SAFE_ASSERT_RETURN(pool.size == fPool.size,);
  221. if (! fMutex.tryLock())
  222. return;
  223. //if (pool.startFrame != fPool.startFrame || pool.buffer[0] != fPool.buffer[0] || pool.buffer[1] != fPool.buffer[1])
  224. {
  225. pool.startFrame = fPool.startFrame;
  226. carla_copyFloats(pool.buffer[0], fPool.buffer[0], fPool.size);
  227. carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.size);
  228. }
  229. fMutex.unlock();
  230. }
  231. void readPoll()
  232. {
  233. if (fFileNfo.frames <= 0 || fFilePtr == nullptr)
  234. {
  235. carla_stderr("R: no song loaded");
  236. fNeedsRead = false;
  237. return;
  238. }
  239. int64_t lastFrame = kPlayer->getLastFrame();
  240. int64_t readFrame = lastFrame;
  241. int64_t maxFrame = fFileNfo.frames;
  242. if (lastFrame >= maxFrame)
  243. {
  244. if (fLoopingMode)
  245. {
  246. carla_debug("R: transport out of bounds for loop");
  247. readFrame %= fMaxPlayerFrame;
  248. }
  249. else
  250. {
  251. carla_stderr("R: transport out of bounds");
  252. fNeedsRead = false;
  253. return;
  254. }
  255. }
  256. // temp data buffer
  257. carla_zeroFloats(fPollTempData, fPollTempSize);
  258. {
  259. carla_debug("R: poll data - reading at %li:%02li", readFrame/fPool.sampleRate/60, (readFrame/fPool.sampleRate) % 60);
  260. ad_seek(fFilePtr, readFrame);
  261. size_t i = 0;
  262. ssize_t j = 0;
  263. ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
  264. if (rv < 0)
  265. {
  266. carla_stderr("R: ad_read failed");
  267. fNeedsRead = false;
  268. return;
  269. }
  270. // see if we can read more
  271. if (readFrame + rv >= static_cast<ssize_t>(fFileNfo.frames) && static_cast<size_t>(rv) < fPollTempSize)
  272. {
  273. carla_debug("R: from start");
  274. ad_seek(fFilePtr, 0);
  275. rv += ad_read(fFilePtr, fPollTempData+rv, fPollTempSize-rv);
  276. }
  277. // lock, and put data asap
  278. const CarlaMutexLocker cml(fMutex);
  279. do {
  280. for (; i < fPool.size && j < rv; ++j)
  281. {
  282. if (fFileNfo.channels == 1)
  283. {
  284. fPool.buffer[0][i] = fPollTempData[j];
  285. fPool.buffer[1][i] = fPollTempData[j];
  286. i++;
  287. }
  288. else
  289. {
  290. if (j % 2 == 0)
  291. {
  292. fPool.buffer[0][i] = fPollTempData[j];
  293. }
  294. else
  295. {
  296. fPool.buffer[1][i] = fPollTempData[j];
  297. i++;
  298. }
  299. }
  300. }
  301. if (i >= fPool.size)
  302. break;
  303. if (rv == fFileNfo.frames)
  304. {
  305. // full file read
  306. j = 0;
  307. carla_debug("R: full file was read, filling buffers again");
  308. }
  309. else
  310. {
  311. carla_debug("read break, not enough space");
  312. // FIXME use carla_zeroFloats
  313. for (; i < fPool.size; ++i)
  314. {
  315. fPool.buffer[0][i] = 0.0f;
  316. fPool.buffer[1][i] = 0.0f;
  317. }
  318. break;
  319. }
  320. } while (i < fPool.size);
  321. fPool.startFrame = lastFrame;
  322. }
  323. fNeedsRead = false;
  324. }
  325. protected:
  326. void run() override
  327. {
  328. while (! fQuitNow)
  329. {
  330. const uint32_t lastFrame = kPlayer->getLastFrame();
  331. const uint32_t loopedFrame = fLoopingMode ? lastFrame % fMaxPlayerFrame : lastFrame;
  332. if (fNeedsRead || lastFrame < fPool.startFrame || (lastFrame - fPool.startFrame >= fPool.size*3/4 && loopedFrame < fMaxPlayerFrame))
  333. readPoll();
  334. else
  335. carla_msleep(50);
  336. }
  337. }
  338. private:
  339. AbstractAudioPlayer* const kPlayer;
  340. bool fLoopingMode;
  341. bool fNeedsRead;
  342. bool fQuitNow;
  343. void* fFilePtr;
  344. ADInfo fFileNfo;
  345. uint32_t fMaxPlayerFrame;
  346. float* fPollTempData;
  347. size_t fPollTempSize;
  348. AudioFilePool fPool;
  349. CarlaMutex fMutex;
  350. };
  351. #endif // AUDIO_BASE_HPP_INCLUDED