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.

381 lines
9.0KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013 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__
  18. #define __AUDIO_BASE_HPP__
  19. #include "CarlaMutex.hpp"
  20. #include <QtCore/QThread>
  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 startFrame;
  28. uint32_t size;
  29. AudioFilePool()
  30. : buffer{nullptr},
  31. startFrame(0),
  32. size(0) {}
  33. ~AudioFilePool()
  34. {
  35. CARLA_ASSERT(buffer[0] == nullptr);
  36. CARLA_ASSERT(buffer[1] == nullptr);
  37. CARLA_ASSERT(startFrame == 0);
  38. CARLA_ASSERT(size == 0);
  39. }
  40. void create(const uint32_t sampleRate)
  41. {
  42. CARLA_ASSERT(buffer[0] == nullptr);
  43. CARLA_ASSERT(buffer[1] == nullptr);
  44. CARLA_ASSERT(startFrame == 0);
  45. CARLA_ASSERT(size == 0);
  46. size = sampleRate * 2;
  47. buffer[0] = new float[size];
  48. buffer[1] = new float[size];
  49. reset();
  50. }
  51. void destroy()
  52. {
  53. CARLA_ASSERT(buffer[0] != nullptr);
  54. CARLA_ASSERT(buffer[1] != nullptr);
  55. CARLA_ASSERT(size != 0);
  56. if (buffer[0] != nullptr)
  57. {
  58. delete[] buffer[0];
  59. buffer[0] = nullptr;
  60. }
  61. if (buffer[1] != nullptr)
  62. {
  63. delete[] buffer[1];
  64. buffer[1] = nullptr;
  65. }
  66. startFrame = 0;
  67. size = 0;
  68. }
  69. void reset()
  70. {
  71. CARLA_ASSERT(size != 0);
  72. startFrame = 0;
  73. carla_zeroFloat(buffer[0], size);
  74. carla_zeroFloat(buffer[1], size);
  75. }
  76. };
  77. class AbstractAudioPlayer
  78. {
  79. public:
  80. virtual ~AbstractAudioPlayer() {}
  81. virtual uint32_t getLastFrame() const = 0;
  82. };
  83. class AudioFileThread : public QThread
  84. {
  85. public:
  86. AudioFileThread(AbstractAudioPlayer* const player, const double sampleRate)
  87. : QThread(nullptr),
  88. kPlayer(player),
  89. fNeedsRead(false),
  90. fQuitNow(true),
  91. fFilePtr(nullptr)
  92. {
  93. CARLA_ASSERT(kPlayer != nullptr);
  94. static bool adInitiated = false;
  95. if (! adInitiated)
  96. {
  97. ad_init();
  98. adInitiated = true;
  99. }
  100. ad_clear_nfo(&fFileNfo);
  101. fPool.create(sampleRate);
  102. }
  103. ~AudioFileThread() override
  104. {
  105. CARLA_ASSERT(fQuitNow);
  106. CARLA_ASSERT(! isRunning());
  107. if (fFilePtr != nullptr)
  108. ad_close(fFilePtr);
  109. fPool.destroy();
  110. }
  111. void startNow()
  112. {
  113. fNeedsRead = true;
  114. fQuitNow = false;
  115. start(IdlePriority);
  116. }
  117. void stopNow()
  118. {
  119. fNeedsRead = false;
  120. fQuitNow = true;
  121. if (isRunning() && ! wait(1000))
  122. terminate();
  123. const CarlaMutex::ScopedLocker sl(&fMutex);
  124. fPool.reset();
  125. }
  126. uint32_t getMaxFrame() const
  127. {
  128. return fFileNfo.frames > 0 ? fFileNfo.frames : 0;
  129. }
  130. void setNeedsRead()
  131. {
  132. fNeedsRead = true;
  133. }
  134. bool loadFilename(const char* const filename)
  135. {
  136. CARLA_ASSERT(! isRunning());
  137. CARLA_ASSERT(filename != nullptr);
  138. fPool.startFrame = 0;
  139. // clear old data
  140. if (fFilePtr != nullptr)
  141. {
  142. ad_close(fFilePtr);
  143. fFilePtr = nullptr;
  144. }
  145. ad_clear_nfo(&fFileNfo);
  146. // open new
  147. fFilePtr = ad_open(filename, &fFileNfo);
  148. if (fFilePtr == nullptr)
  149. return false;
  150. ad_dump_nfo(99, &fFileNfo);
  151. if (fFileNfo.frames == 0)
  152. carla_stderr("L: filename \"%s\" has 0 frames", filename);
  153. if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
  154. {
  155. // valid
  156. readPoll();
  157. return true;
  158. }
  159. else
  160. {
  161. // invalid
  162. ad_clear_nfo(&fFileNfo);
  163. ad_close(fFilePtr);
  164. fFilePtr = nullptr;
  165. return false;
  166. }
  167. }
  168. void tryPutData(AudioFilePool& pool)
  169. {
  170. CARLA_ASSERT(pool.size == fPool.size);
  171. if (pool.size != fPool.size)
  172. return;
  173. if (! fMutex.tryLock())
  174. return;
  175. //if (pool.startFrame != fPool.startFrame || pool.buffer[0] != fPool.buffer[0] || pool.buffer[1] != fPool.buffer[1])
  176. {
  177. pool.startFrame = fPool.startFrame;
  178. carla_copyFloat(pool.buffer[0], fPool.buffer[0], fPool.size);
  179. carla_copyFloat(pool.buffer[1], fPool.buffer[1], fPool.size);
  180. }
  181. fMutex.unlock();
  182. }
  183. void readPoll()
  184. {
  185. if (fFileNfo.frames <= 0 || fFilePtr == nullptr)
  186. {
  187. carla_stderr("R: no song loaded");
  188. fNeedsRead = false;
  189. return;
  190. }
  191. int64_t lastFrame = kPlayer->getLastFrame();
  192. int64_t readFrame = lastFrame;
  193. int64_t maxFrame = fFileNfo.frames;
  194. if (lastFrame >= maxFrame)
  195. {
  196. #if 0
  197. if (false)
  198. //if (handlePtr->loopMode)
  199. {
  200. carla_stderr("R: DEBUG read loop, lastFrame:%i, maxFrame:%i", lastFrame, maxFrame);
  201. if (maxFrame >= static_cast<int64_t>(fPool.size))
  202. {
  203. readFrame %= maxFrame;
  204. }
  205. else
  206. {
  207. readFrame = 0;
  208. lastFrame -= lastFrame % maxFrame;
  209. }
  210. }
  211. else
  212. #endif
  213. {
  214. carla_stderr("R: transport out of bounds");
  215. fNeedsRead = false;
  216. return;
  217. }
  218. }
  219. // temp data buffer
  220. const size_t tmpSize = fPool.size * fFileNfo.channels;
  221. float tmpData[tmpSize];
  222. carla_zeroFloat(tmpData, tmpSize);
  223. {
  224. carla_stderr("R: poll data - reading at %li:%02li", readFrame/44100/60, (readFrame/44100) % 60);
  225. ad_seek(fFilePtr, readFrame);
  226. ssize_t i, j, rv = ad_read(fFilePtr, tmpData, tmpSize);
  227. i = j = 0;
  228. // lock, and put data asap
  229. const CarlaMutex::ScopedLocker sl(&fMutex);
  230. for (; i < fPool.size && j < rv; ++j)
  231. {
  232. if (fFileNfo.channels == 1)
  233. {
  234. fPool.buffer[0][i] = tmpData[j];
  235. fPool.buffer[1][i] = tmpData[j];
  236. i++;
  237. }
  238. else
  239. {
  240. if (j % 2 == 0)
  241. {
  242. fPool.buffer[0][i] = tmpData[j];
  243. }
  244. else
  245. {
  246. fPool.buffer[1][i] = tmpData[j];
  247. i++;
  248. }
  249. }
  250. }
  251. #if 0
  252. if (false)
  253. //if (handlePtr->loopMode && i < fPool.size)
  254. {
  255. while (i < fPool.size)
  256. {
  257. for (j=0; i < fPool.size && j < rv; ++j)
  258. {
  259. if (fFileNfo.channels == 1)
  260. {
  261. fPool.buffer[0][i] = tmpData[j];
  262. fPool.buffer[1][i] = tmpData[j];
  263. i++;
  264. }
  265. else
  266. {
  267. if (j % 2 == 0)
  268. {
  269. fPool.buffer[0][i] = tmpData[j];
  270. }
  271. else
  272. {
  273. fPool.buffer[1][i] = tmpData[j];
  274. i++;
  275. }
  276. }
  277. }
  278. }
  279. }
  280. else
  281. #endif
  282. {
  283. for (; i < fPool.size; ++i)
  284. {
  285. fPool.buffer[0][i] = 0.0f;
  286. fPool.buffer[1][i] = 0.0f;
  287. }
  288. }
  289. fPool.startFrame = lastFrame;
  290. }
  291. fNeedsRead = false;
  292. }
  293. protected:
  294. void run() override
  295. {
  296. while (! fQuitNow)
  297. {
  298. const uint32_t lastFrame(kPlayer->getLastFrame());
  299. if (fNeedsRead || lastFrame < fPool.startFrame || (lastFrame - fPool.startFrame >= fPool.size*3/4 && lastFrame < fFileNfo.frames))
  300. readPoll();
  301. else
  302. carla_msleep(50);
  303. }
  304. }
  305. private:
  306. AbstractAudioPlayer* const kPlayer;
  307. bool fNeedsRead;
  308. bool fQuitNow;
  309. void* fFilePtr;
  310. ADInfo fFileNfo;
  311. AudioFilePool fPool;
  312. CarlaMutex fMutex;
  313. };
  314. #endif // __AUDIO_BASE_HPP__