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.

379 lines
9.1KB

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