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.

743 lines
25KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2023 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 "CarlaMathUtils.hpp"
  20. #include "CarlaMemUtils.hpp"
  21. #include "CarlaRingBuffer.hpp"
  22. extern "C" {
  23. #include "audio_decoder/ad.h"
  24. }
  25. // #include "water/threads/ScopedLock.h"
  26. // #include "water/threads/SpinLock.h"
  27. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  28. # pragma GCC diagnostic push
  29. # pragma GCC diagnostic ignored "-Weffc++"
  30. #endif
  31. #include "zita-resampler/resampler.h"
  32. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  33. # pragma GCC diagnostic pop
  34. #endif
  35. #define DEBUG_FILE_OPS
  36. typedef struct adinfo ADInfo;
  37. // --------------------------------------------------------------------------------------------------------------------
  38. // tuning
  39. // disk streaming buffer size
  40. static constexpr const uint16_t kFileReaderBufferSize = 1024;
  41. // if reading a file smaller than this, load it all in memory
  42. static constexpr const uint16_t kMinLengthSeconds = 30;
  43. // size of the audio file ring buffer
  44. static constexpr const uint16_t kRingBufferLengthSeconds = 6;
  45. // --------------------------------------------------------------------------------------------------------------------
  46. struct AudioMemoryPool {
  47. float* buffer[2] = {};
  48. uint32_t numFrames = 0;
  49. CarlaMutex mutex;
  50. AudioMemoryPool() noexcept {}
  51. ~AudioMemoryPool() noexcept
  52. {
  53. destroy();
  54. }
  55. void create(const uint32_t desiredNumFrames)
  56. {
  57. CARLA_ASSERT(buffer[0] == nullptr);
  58. CARLA_ASSERT(buffer[1] == nullptr);
  59. CARLA_ASSERT(numFrames == 0);
  60. buffer[0] = new float[desiredNumFrames];
  61. buffer[1] = new float[desiredNumFrames];
  62. carla_mlock(buffer[0], sizeof(float)*desiredNumFrames);
  63. carla_mlock(buffer[1], sizeof(float)*desiredNumFrames);
  64. const CarlaMutexLocker cml(mutex);
  65. numFrames = desiredNumFrames;
  66. }
  67. void destroy() noexcept
  68. {
  69. {
  70. const CarlaMutexLocker cml(mutex);
  71. numFrames = 0;
  72. }
  73. if (buffer[0] != nullptr)
  74. {
  75. delete[] buffer[0];
  76. buffer[0] = nullptr;
  77. }
  78. if (buffer[1] != nullptr)
  79. {
  80. delete[] buffer[1];
  81. buffer[1] = nullptr;
  82. }
  83. }
  84. CARLA_DECLARE_NON_COPYABLE(AudioMemoryPool)
  85. };
  86. // --------------------------------------------------------------------------------------------------------------------
  87. class AudioFileReader
  88. {
  89. public:
  90. AudioFileReader()
  91. {
  92. ad_clear_nfo(&fFileNfo);
  93. }
  94. ~AudioFileReader()
  95. {
  96. destroy();
  97. }
  98. void destroy()
  99. {
  100. const CarlaMutexLocker cml(fReaderMutex);
  101. cleanup();
  102. }
  103. int getCurrentBitRate() const noexcept
  104. {
  105. return fCurrentBitRate;
  106. }
  107. float getLastPlayPosition() const noexcept
  108. {
  109. return fLastPlayPosition;
  110. }
  111. float getReadableBufferFill() const noexcept
  112. {
  113. if (fFileNfo.channels == 0)
  114. return 0.f;
  115. if (fEntireFileLoaded)
  116. return 1.f;
  117. return 1.f - (static_cast<float>(fRingBufferR.getReadableDataSize() / sizeof(float))
  118. / static_cast<float>(fRingBufferR.getSize() / sizeof(float)));
  119. }
  120. ADInfo getFileInfo() const noexcept
  121. {
  122. return fFileNfo;
  123. }
  124. bool loadFilename(const char* const filename, const uint32_t sampleRate,
  125. const uint32_t previewDataSize, float* previewData)
  126. {
  127. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
  128. const CarlaMutexLocker cml(fReaderMutex);
  129. cleanup();
  130. ad_clear_nfo(&fFileNfo);
  131. // open new
  132. fFilePtr = ad_open(filename, &fFileNfo);
  133. if (fFilePtr == nullptr)
  134. return false;
  135. ad_dump_nfo(99, &fFileNfo);
  136. // invalid
  137. if ((fFileNfo.channels != 1 && fFileNfo.channels != 2) || fFileNfo.frames <= 0)
  138. {
  139. if (fFileNfo.channels != 1 && fFileNfo.channels != 2)
  140. carla_stderr("loadFilename(\"%s\", ...) has not 1 or 2 channels", filename);
  141. if (fFileNfo.frames <= 0)
  142. carla_stderr("loadFilename(\"%s\", ...) has 0 frames", filename);
  143. ad_clear_nfo(&fFileNfo);
  144. ad_close(fFilePtr);
  145. fFilePtr = nullptr;
  146. return false;
  147. }
  148. const uint64_t numFileFrames = static_cast<uint64_t>(fFileNfo.frames);
  149. const bool needsResample = fFileNfo.sample_rate != sampleRate;
  150. uint64_t numResampledFrames;
  151. if (needsResample)
  152. {
  153. if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32))
  154. {
  155. ad_clear_nfo(&fFileNfo);
  156. ad_close(fFilePtr);
  157. fFilePtr = nullptr;
  158. carla_stderr2("loadFilename(\"%s\", ...) error, resampler setup failed");
  159. return false;
  160. }
  161. fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
  162. numResampledFrames = static_cast<uint64_t>(static_cast<double>(numFileFrames) * fResampleRatio + 0.5);
  163. if (fPreviousResampledBuffer.buffer == nullptr)
  164. fPreviousResampledBuffer.buffer = new float[kFileReaderBufferSize];
  165. }
  166. else
  167. {
  168. numResampledFrames = numFileFrames;
  169. }
  170. if (fFileNfo.can_seek == 0 || numResampledFrames <= sampleRate * kMinLengthSeconds)
  171. {
  172. // read and cache the first few seconds of the file if seekable
  173. const uint64_t initialFrames = fFileNfo.can_seek == 0
  174. ? numFileFrames
  175. : std::min<uint64_t>(numFileFrames, fFileNfo.sample_rate * kMinLengthSeconds);
  176. const uint64_t initialResampledFrames = fFileNfo.can_seek == 0
  177. ? numResampledFrames
  178. : std::min<uint64_t>(numResampledFrames,
  179. sampleRate * kMinLengthSeconds);
  180. fInitialMemoryPool.create(initialResampledFrames);
  181. readIntoInitialMemoryPool(initialFrames, initialResampledFrames);
  182. // file is no longer needed, we have it all in memory
  183. ad_close(fFilePtr);
  184. fFilePtr = nullptr;
  185. const float resampledFramesF = static_cast<float>(numResampledFrames);
  186. const float previewDataSizeF = static_cast<float>(previewDataSize);
  187. for (uint i=0; i<previewDataSize; ++i)
  188. {
  189. const float stepF = static_cast<float>(i)/previewDataSizeF * resampledFramesF;
  190. const uint step = carla_fixedValue<uint64_t>(0, numResampledFrames-1, static_cast<uint>(stepF + 0.5f));
  191. previewData[i] = std::max(std::fabs(fInitialMemoryPool.buffer[0][step]),
  192. std::fabs(fInitialMemoryPool.buffer[1][step]));
  193. }
  194. fEntireFileLoaded = true;
  195. }
  196. else
  197. {
  198. readFilePreview(previewDataSize, previewData);
  199. // cache only the first few initial seconds, let disk streaming handle the rest
  200. const uint64_t initialFrames = std::min<uint64_t>(numFileFrames,
  201. fFileNfo.sample_rate * kRingBufferLengthSeconds / 2);
  202. const uint64_t initialResampledFrames = std::min<uint64_t>(numResampledFrames,
  203. sampleRate * kRingBufferLengthSeconds / 2);
  204. fRingBufferL.createBuffer(sampleRate * kRingBufferLengthSeconds * sizeof(float), true);
  205. fRingBufferR.createBuffer(sampleRate * kRingBufferLengthSeconds * sizeof(float), true);
  206. fInitialMemoryPool.create(initialResampledFrames);
  207. readIntoInitialMemoryPool(initialFrames, initialResampledFrames);
  208. fRingBufferL.writeCustomData(fInitialMemoryPool.buffer[0], fInitialMemoryPool.numFrames * sizeof(float));
  209. fRingBufferR.writeCustomData(fInitialMemoryPool.buffer[1], fInitialMemoryPool.numFrames * sizeof(float));
  210. fRingBufferL.commitWrite();
  211. fRingBufferR.commitWrite();
  212. fEntireFileLoaded = false;
  213. }
  214. fTotalResampledFrames = numResampledFrames;
  215. fSampleRate = sampleRate;
  216. return true;
  217. }
  218. bool tickFrames(float* const buffers[],
  219. uint32_t bufferOffset, uint32_t frames, uint64_t framePos,
  220. const bool loopingMode, const bool isOffline)
  221. {
  222. float* outL = buffers[0] + bufferOffset;
  223. float* outR = buffers[1] + bufferOffset;
  224. float* playCV = buffers[2] + bufferOffset;
  225. if (loopingMode && framePos >= fTotalResampledFrames)
  226. framePos %= fTotalResampledFrames;
  227. if (framePos >= fTotalResampledFrames)
  228. {
  229. carla_zeroFloats(outL, frames);
  230. carla_zeroFloats(outR, frames);
  231. carla_zeroFloats(playCV, frames);
  232. fLastPlayPosition = 1.f;
  233. return false;
  234. }
  235. uint32_t numPoolFrames, usableFrames;
  236. {
  237. const CarlaMutexTryLocker cmtl(fInitialMemoryPool.mutex, isOffline);
  238. numPoolFrames = fInitialMemoryPool.numFrames;
  239. if (numPoolFrames == 0 || ! cmtl.wasLocked())
  240. {
  241. carla_zeroFloats(outL, frames);
  242. carla_zeroFloats(outR, frames);
  243. carla_zeroFloats(playCV, frames);
  244. return false;
  245. }
  246. if (framePos < numPoolFrames)
  247. {
  248. usableFrames = std::min(frames, numPoolFrames - static_cast<uint32_t>(framePos));
  249. carla_copyFloats(outL, fInitialMemoryPool.buffer[0] + framePos, usableFrames);
  250. carla_copyFloats(outR, fInitialMemoryPool.buffer[1] + framePos, usableFrames);
  251. carla_fillFloatsWithSingleValue(playCV, 10.f, usableFrames);
  252. outL += usableFrames;
  253. outR += usableFrames;
  254. playCV += usableFrames;
  255. bufferOffset += usableFrames;
  256. framePos += usableFrames;
  257. frames -= usableFrames;
  258. }
  259. if (fEntireFileLoaded && frames != 0)
  260. return tickFrames(buffers, bufferOffset, frames, framePos, loopingMode, isOffline);
  261. }
  262. fLastPlayPosition = static_cast<float>(framePos / 64) / static_cast<float>(fTotalResampledFrames / 64);
  263. if (fEntireFileLoaded)
  264. return false;
  265. if (frames == 0)
  266. {
  267. // ring buffer is good, waiting for data reads
  268. if (fRingBufferFramePos == numPoolFrames)
  269. return false;
  270. // out of bounds, host likely has repositioned transport
  271. if (fRingBufferFramePos > numPoolFrames)
  272. {
  273. fNextFileReadPos = 0;
  274. carla_stdout("tickFrames read from start");
  275. return true;
  276. }
  277. // within bounds, skip frames until we reach the end of the memory pool
  278. if (fRingBufferR.getReadableDataSize() >= numPoolFrames * sizeof(float))
  279. {
  280. fRingBufferL.skipRead(numPoolFrames * sizeof(float));
  281. fRingBufferR.skipRead(numPoolFrames * sizeof(float));
  282. fRingBufferFramePos = numPoolFrames;
  283. carla_stdout("tickFrames adjusted frame pos from start");
  284. }
  285. return true;
  286. }
  287. uint32_t totalFramesAvailable = fRingBufferR.getReadableDataSize() / sizeof(float);
  288. if (framePos != fRingBufferFramePos)
  289. {
  290. // unaligned position, see if we need to relocate too
  291. if (framePos < fRingBufferFramePos || framePos >= fRingBufferFramePos + totalFramesAvailable - frames)
  292. {
  293. carla_zeroFloats(outL, frames);
  294. carla_zeroFloats(outR, frames);
  295. carla_zeroFloats(playCV, frames);
  296. // wait until there previous relocation is done
  297. if (fNextFileReadPos == -1)
  298. fNextFileReadPos = framePos;
  299. return true;
  300. }
  301. // oh nice, we can skip a few frames and be in sync
  302. const uint32_t diffFrames = framePos - fRingBufferFramePos;
  303. fRingBufferL.skipRead(diffFrames * sizeof(float));
  304. fRingBufferR.skipRead(diffFrames * sizeof(float));
  305. totalFramesAvailable -= diffFrames;
  306. fRingBufferFramePos = framePos;
  307. carla_stdout("tickFrames adjusted frame unaligned position");
  308. }
  309. usableFrames = std::min<uint32_t>(frames, totalFramesAvailable);
  310. if (usableFrames == 0)
  311. {
  312. carla_stdout("tickFrames no more usable frames %lu %lu %u", framePos, fRingBufferFramePos, totalFramesAvailable);
  313. carla_zeroFloats(outL, frames);
  314. carla_zeroFloats(outR, frames);
  315. carla_zeroFloats(playCV, frames);
  316. return framePos < fTotalResampledFrames;
  317. }
  318. fRingBufferL.readCustomData(outL, sizeof(float) * usableFrames);
  319. fRingBufferR.readCustomData(outR, sizeof(float) * usableFrames);
  320. carla_fillFloatsWithSingleValue(playCV, 10.f, usableFrames);
  321. fRingBufferFramePos += usableFrames;
  322. totalFramesAvailable -= usableFrames;
  323. if (frames != usableFrames)
  324. {
  325. if (loopingMode)
  326. {
  327. bufferOffset += usableFrames;
  328. framePos += usableFrames;
  329. frames -= usableFrames;
  330. carla_stdout("tickFrames looping return");
  331. return tickFrames(buffers, bufferOffset, frames, framePos, loopingMode, isOffline);
  332. }
  333. carla_stdout("tickFrames partial usable frames");
  334. carla_zeroFloats(outL + usableFrames, frames - usableFrames);
  335. carla_zeroFloats(outR + usableFrames, frames - usableFrames);
  336. carla_zeroFloats(playCV + usableFrames, frames - usableFrames);
  337. }
  338. return totalFramesAvailable <= fSampleRate * 2;
  339. }
  340. void readFilePreview(uint32_t previewDataSize, float* const previewData)
  341. {
  342. carla_zeroFloats(previewData, previewDataSize);
  343. if (fFileNfo.can_seek == 0)
  344. return;
  345. const uint fileNumFrames = static_cast<uint>(fFileNfo.frames);
  346. const float fileNumFramesF = static_cast<float>(fileNumFrames);
  347. const float previewDataSizeF = static_cast<float>(previewDataSize);
  348. const uint samplesPerRun = fFileNfo.channels;
  349. const uint maxSampleToRead = fileNumFrames - samplesPerRun;
  350. CARLA_SAFE_ASSERT_INT_RETURN(samplesPerRun == 1 || samplesPerRun == 2, samplesPerRun,);
  351. float tmp[2] = { 0.0f, 0.0f };
  352. if (samplesPerRun == 2)
  353. previewDataSize -= 1;
  354. for (uint i=0; i<previewDataSize; ++i)
  355. {
  356. const float posF = static_cast<float>(i)/previewDataSizeF * fileNumFramesF;
  357. const uint pos = carla_fixedValue(0U, maxSampleToRead, static_cast<uint>(posF));
  358. ad_seek(fFilePtr, pos);
  359. ad_read(fFilePtr, tmp, samplesPerRun);
  360. previewData[i] = std::max(std::fabs(tmp[0]), std::fabs(tmp[1]));
  361. }
  362. }
  363. void readPoll()
  364. {
  365. const CarlaMutexLocker cml(fReaderMutex);
  366. const uint channels = fFileNfo.channels;
  367. if (channels == 0 || fFilePtr == nullptr)
  368. {
  369. carla_debug("R: no song loaded");
  370. return;
  371. }
  372. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  373. const bool needsResample = carla_isNotEqual(fResampleRatio, 1.0);
  374. const int64_t nextFileReadPos = fNextFileReadPos;
  375. if (nextFileReadPos != -1)
  376. {
  377. carla_stdout("readPoll new pos %lu", nextFileReadPos);
  378. fRingBufferL.flush();
  379. fRingBufferR.flush();
  380. fPreviousResampledBuffer.frames = 0;
  381. fRingBufferFramePos = nextFileReadPos;
  382. ad_seek(fFilePtr, nextFileReadPos / fResampleRatio);
  383. if (needsResample)
  384. fResampler.reset();
  385. }
  386. if (needsResample)
  387. {
  388. float buffer[kFileReaderBufferSize];
  389. float rbuffer[kFileReaderBufferSize];
  390. ssize_t r;
  391. uint prev_inp_count = 0;
  392. while (fRingBufferR.getWritableDataSize() >= sizeof(rbuffer))
  393. {
  394. if (const uint32_t oldframes = fPreviousResampledBuffer.frames)
  395. {
  396. prev_inp_count = oldframes;
  397. fPreviousResampledBuffer.frames = 0;
  398. std::memcpy(buffer, fPreviousResampledBuffer.buffer, sizeof(float) * oldframes * channels);
  399. }
  400. else if (prev_inp_count != 0)
  401. {
  402. std::memmove(buffer,
  403. buffer + (sizeof(buffer) / sizeof(float) - prev_inp_count * channels),
  404. sizeof(float) * prev_inp_count * channels);
  405. }
  406. r = ad_read(fFilePtr,
  407. buffer + (prev_inp_count * channels),
  408. sizeof(buffer) / sizeof(float) - (prev_inp_count * channels));
  409. if (r < 0)
  410. {
  411. carla_stderr("R: ad_read failed");
  412. break;
  413. }
  414. if (r == 0)
  415. break;
  416. fResampler.inp_count = prev_inp_count + r / channels;
  417. fResampler.out_count = sizeof(rbuffer) / sizeof(float) / channels;
  418. fResampler.inp_data = buffer;
  419. fResampler.out_data = rbuffer;
  420. fResampler.process();
  421. r = sizeof(rbuffer) / sizeof(float) - fResampler.out_count * channels;
  422. if (fResampleRatio > 1.0)
  423. {
  424. if (fResampler.out_count == 0)
  425. {
  426. CARLA_SAFE_ASSERT_UINT(fResampler.inp_count != 0, fResampler.inp_count);
  427. }
  428. else
  429. {
  430. CARLA_SAFE_ASSERT_UINT(fResampler.inp_count == 0, fResampler.inp_count);
  431. }
  432. }
  433. else
  434. {
  435. CARLA_SAFE_ASSERT(fResampler.inp_count == 0);
  436. }
  437. prev_inp_count = fResampler.inp_count;
  438. if (r == 0)
  439. break;
  440. if (channels == 1)
  441. {
  442. fRingBufferL.writeCustomData(rbuffer, r * sizeof(float));
  443. fRingBufferR.writeCustomData(rbuffer, r * sizeof(float));
  444. }
  445. else
  446. {
  447. for (ssize_t i=0; i < r;)
  448. {
  449. fRingBufferL.writeCustomData(&rbuffer[i++], sizeof(float));
  450. fRingBufferR.writeCustomData(&rbuffer[i++], sizeof(float));
  451. }
  452. }
  453. fRingBufferL.commitWrite();
  454. fRingBufferR.commitWrite();
  455. }
  456. if (prev_inp_count != 0)
  457. {
  458. fPreviousResampledBuffer.frames = prev_inp_count;
  459. std::memcpy(fPreviousResampledBuffer.buffer,
  460. buffer + (sizeof(buffer) / sizeof(float) - prev_inp_count * channels),
  461. sizeof(float) * prev_inp_count * channels);
  462. }
  463. }
  464. else
  465. {
  466. float buffer[kFileReaderBufferSize];
  467. ssize_t r;
  468. while (fRingBufferR.getWritableDataSize() >= sizeof(buffer))
  469. {
  470. r = ad_read(fFilePtr, buffer, sizeof(buffer)/sizeof(float));
  471. if (r < 0)
  472. {
  473. carla_stderr("R: ad_read failed");
  474. break;
  475. }
  476. if (r == 0)
  477. break;
  478. if (channels == 1)
  479. {
  480. fRingBufferL.writeCustomData(buffer, r * sizeof(float));
  481. fRingBufferR.writeCustomData(buffer, r * sizeof(float));
  482. }
  483. else
  484. {
  485. for (ssize_t i=0; i < r;)
  486. {
  487. fRingBufferL.writeCustomData(&buffer[i++], sizeof(float));
  488. fRingBufferR.writeCustomData(&buffer[i++], sizeof(float));
  489. }
  490. }
  491. fRingBufferL.commitWrite();
  492. fRingBufferR.commitWrite();
  493. }
  494. }
  495. if (nextFileReadPos != -1)
  496. fNextFileReadPos = -1;
  497. }
  498. private:
  499. bool fEntireFileLoaded = false;
  500. int fCurrentBitRate = 0;
  501. float fLastPlayPosition = 0.f;
  502. int64_t fNextFileReadPos = -1;
  503. uint64_t fTotalResampledFrames = 0;
  504. void* fFilePtr = nullptr;
  505. ADInfo fFileNfo = {};
  506. uint32_t fSampleRate = 0;
  507. double fResampleRatio = 1.0;
  508. AudioMemoryPool fInitialMemoryPool;
  509. Resampler fResampler;
  510. CarlaMutex fReaderMutex;
  511. struct PreviousResampledBuffer {
  512. float* buffer = nullptr;
  513. uint32_t frames = 0;
  514. } fPreviousResampledBuffer;
  515. CarlaHeapRingBuffer fRingBufferL, fRingBufferR;
  516. uint64_t fRingBufferFramePos = 0;
  517. // assumes reader lock is active
  518. void cleanup()
  519. {
  520. fEntireFileLoaded = false;
  521. fCurrentBitRate = 0;
  522. fLastPlayPosition = 0.f;
  523. fNextFileReadPos = -1;
  524. fTotalResampledFrames = 0;
  525. fSampleRate = 0;
  526. fRingBufferFramePos = 0;
  527. fResampleRatio = 1.0;
  528. fResampler.clear();
  529. fInitialMemoryPool.destroy();
  530. fRingBufferL.deleteBuffer();
  531. fRingBufferR.deleteBuffer();
  532. if (fFilePtr != nullptr)
  533. {
  534. ad_close(fFilePtr);
  535. fFilePtr = nullptr;
  536. }
  537. delete[] fPreviousResampledBuffer.buffer;
  538. fPreviousResampledBuffer.buffer = nullptr;
  539. fPreviousResampledBuffer.frames = 0;
  540. }
  541. void readIntoInitialMemoryPool(const uint numFrames, const uint numResampledFrames)
  542. {
  543. const uint channels = fFileNfo.channels;
  544. const uint fileBufferSize = numFrames * channels;
  545. float* const fileBuffer = (float*)std::malloc(fileBufferSize * sizeof(float));
  546. CARLA_SAFE_ASSERT_RETURN(fileBuffer != nullptr,);
  547. ad_seek(fFilePtr, 0);
  548. ssize_t rv = ad_read(fFilePtr, fileBuffer, fileBufferSize);
  549. CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(fileBufferSize),
  550. rv, fileBufferSize,
  551. std::free(fileBuffer));
  552. fCurrentBitRate = ad_get_bitrate(fFilePtr);
  553. float* resampledBuffer;
  554. if (numFrames != numResampledFrames)
  555. {
  556. resampledBuffer = (float*)std::malloc(numResampledFrames * channels * sizeof(float));
  557. CARLA_SAFE_ASSERT_RETURN(resampledBuffer != nullptr, std::free(fileBuffer););
  558. fResampler.inp_count = numFrames;
  559. fResampler.out_count = numResampledFrames;
  560. fResampler.inp_data = fileBuffer;
  561. fResampler.out_data = resampledBuffer;
  562. fResampler.process();
  563. fInitialMemoryPool.numFrames = numResampledFrames - fResampler.out_count;
  564. rv = fInitialMemoryPool.numFrames * channels;
  565. }
  566. else
  567. {
  568. resampledBuffer = fileBuffer;
  569. }
  570. {
  571. // lock, and put data asap
  572. const CarlaMutexLocker cml(fInitialMemoryPool.mutex);
  573. if (channels == 1)
  574. {
  575. for (ssize_t i=0; i < rv; ++i)
  576. fInitialMemoryPool.buffer[0][i] = fInitialMemoryPool.buffer[1][i] = resampledBuffer[i];
  577. }
  578. else
  579. {
  580. for (ssize_t i=0, j=0; i < rv; ++j)
  581. {
  582. fInitialMemoryPool.buffer[0][j] = resampledBuffer[i++];
  583. fInitialMemoryPool.buffer[1][j] = resampledBuffer[i++];
  584. }
  585. }
  586. }
  587. if (resampledBuffer != fileBuffer)
  588. std::free(resampledBuffer);
  589. std::free(fileBuffer);
  590. }
  591. CARLA_DECLARE_NON_COPYABLE(AudioFileReader)
  592. };
  593. // --------------------------------------------------------------------------------------------------------------------
  594. #endif // AUDIO_BASE_HPP_INCLUDED