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.

657 lines
22KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. AudioSampleBuffer::AudioSampleBuffer (const int numChans,
  18. const int numSamples) noexcept
  19. : numChannels (numChans),
  20. size (numSamples)
  21. {
  22. jassert (numSamples >= 0);
  23. jassert (numChans > 0);
  24. allocateData();
  25. }
  26. AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) noexcept
  27. : numChannels (other.numChannels),
  28. size (other.size),
  29. allocatedBytes (other.allocatedBytes)
  30. {
  31. if (allocatedBytes == 0)
  32. {
  33. allocateChannels (other.channels, 0);
  34. }
  35. else
  36. {
  37. allocateData();
  38. if (other.isClear)
  39. {
  40. clear();
  41. }
  42. else
  43. {
  44. for (int i = 0; i < numChannels; ++i)
  45. FloatVectorOperations::copy (channels[i], other.channels[i], size);
  46. }
  47. }
  48. }
  49. void AudioSampleBuffer::allocateData()
  50. {
  51. const size_t channelListSize = sizeof (float*) * (size_t) (numChannels + 1);
  52. allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (float) + channelListSize + 32;
  53. allocatedData.malloc (allocatedBytes);
  54. channels = reinterpret_cast <float**> (allocatedData.getData());
  55. float* chan = (float*) (allocatedData + channelListSize);
  56. for (int i = 0; i < numChannels; ++i)
  57. {
  58. channels[i] = chan;
  59. chan += size;
  60. }
  61. channels [numChannels] = nullptr;
  62. isClear = false;
  63. }
  64. AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo,
  65. const int numChans,
  66. const int numSamples) noexcept
  67. : numChannels (numChans),
  68. size (numSamples),
  69. allocatedBytes (0)
  70. {
  71. jassert (numChans > 0);
  72. allocateChannels (dataToReferTo, 0);
  73. }
  74. AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo,
  75. const int numChans,
  76. const int startSample,
  77. const int numSamples) noexcept
  78. : numChannels (numChans),
  79. size (numSamples),
  80. allocatedBytes (0),
  81. isClear (false)
  82. {
  83. jassert (numChans > 0);
  84. allocateChannels (dataToReferTo, startSample);
  85. }
  86. void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo,
  87. const int newNumChannels,
  88. const int newNumSamples) noexcept
  89. {
  90. jassert (newNumChannels > 0);
  91. allocatedBytes = 0;
  92. allocatedData.free();
  93. numChannels = newNumChannels;
  94. size = newNumSamples;
  95. allocateChannels (dataToReferTo, 0);
  96. jassert (! isClear);
  97. }
  98. void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int offset)
  99. {
  100. // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools)
  101. if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
  102. {
  103. channels = static_cast <float**> (preallocatedChannelSpace);
  104. }
  105. else
  106. {
  107. allocatedData.malloc ((size_t) numChannels + 1, sizeof (float*));
  108. channels = reinterpret_cast <float**> (allocatedData.getData());
  109. }
  110. for (int i = 0; i < numChannels; ++i)
  111. {
  112. // you have to pass in the same number of valid pointers as numChannels
  113. jassert (dataToReferTo[i] != nullptr);
  114. channels[i] = dataToReferTo[i] + offset;
  115. }
  116. channels [numChannels] = nullptr;
  117. isClear = false;
  118. }
  119. AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) noexcept
  120. {
  121. if (this != &other)
  122. {
  123. setSize (other.getNumChannels(), other.getNumSamples(), false, false, false);
  124. if (other.isClear)
  125. {
  126. clear();
  127. }
  128. else
  129. {
  130. for (int i = 0; i < numChannels; ++i)
  131. FloatVectorOperations::copy (channels[i], other.channels[i], size);
  132. }
  133. }
  134. return *this;
  135. }
  136. AudioSampleBuffer::~AudioSampleBuffer() noexcept
  137. {
  138. }
  139. void AudioSampleBuffer::setSize (const int newNumChannels,
  140. const int newNumSamples,
  141. const bool keepExistingContent,
  142. const bool clearExtraSpace,
  143. const bool avoidReallocating) noexcept
  144. {
  145. jassert (newNumChannels > 0);
  146. jassert (newNumSamples >= 0);
  147. if (newNumSamples != size || newNumChannels != numChannels)
  148. {
  149. const size_t allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u;
  150. const size_t channelListSize = ((sizeof (float*) * (size_t) (newNumChannels + 1)) + 15) & ~15u;
  151. const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (float))
  152. + channelListSize + 32;
  153. if (keepExistingContent)
  154. {
  155. HeapBlock<char, true> newData;
  156. newData.allocate (newTotalBytes, clearExtraSpace || isClear);
  157. const size_t numSamplesToCopy = (size_t) jmin (newNumSamples, size);
  158. float** const newChannels = reinterpret_cast<float**> (newData.getData());
  159. float* newChan = reinterpret_cast<float*> (newData + channelListSize);
  160. for (int j = 0; j < newNumChannels; ++j)
  161. {
  162. newChannels[j] = newChan;
  163. newChan += allocatedSamplesPerChannel;
  164. }
  165. if (! isClear)
  166. {
  167. const int numChansToCopy = jmin (numChannels, newNumChannels);
  168. for (int i = 0; i < numChansToCopy; ++i)
  169. FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy);
  170. }
  171. allocatedData.swapWith (newData);
  172. allocatedBytes = newTotalBytes;
  173. channels = newChannels;
  174. }
  175. else
  176. {
  177. if (avoidReallocating && allocatedBytes >= newTotalBytes)
  178. {
  179. if (clearExtraSpace || isClear)
  180. allocatedData.clear (newTotalBytes);
  181. }
  182. else
  183. {
  184. allocatedBytes = newTotalBytes;
  185. allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear);
  186. channels = reinterpret_cast<float**> (allocatedData.getData());
  187. }
  188. float* chan = reinterpret_cast<float*> (allocatedData + channelListSize);
  189. for (int i = 0; i < newNumChannels; ++i)
  190. {
  191. channels[i] = chan;
  192. chan += allocatedSamplesPerChannel;
  193. }
  194. }
  195. channels [newNumChannels] = 0;
  196. size = newNumSamples;
  197. numChannels = newNumChannels;
  198. }
  199. }
  200. void AudioSampleBuffer::clear() noexcept
  201. {
  202. if (! isClear)
  203. {
  204. for (int i = 0; i < numChannels; ++i)
  205. FloatVectorOperations::clear (channels[i], size);
  206. isClear = true;
  207. }
  208. }
  209. void AudioSampleBuffer::clear (const int startSample,
  210. const int numSamples) noexcept
  211. {
  212. jassert (startSample >= 0 && startSample + numSamples <= size);
  213. if (! isClear)
  214. {
  215. if (startSample == 0 && numSamples == size)
  216. isClear = true;
  217. for (int i = 0; i < numChannels; ++i)
  218. FloatVectorOperations::clear (channels[i] + startSample, numSamples);
  219. }
  220. }
  221. void AudioSampleBuffer::clear (const int channel,
  222. const int startSample,
  223. const int numSamples) noexcept
  224. {
  225. jassert (isPositiveAndBelow (channel, numChannels));
  226. jassert (startSample >= 0 && startSample + numSamples <= size);
  227. if (! isClear)
  228. FloatVectorOperations::clear (channels [channel] + startSample, numSamples);
  229. }
  230. float AudioSampleBuffer::getSample (int channel, int index) const noexcept
  231. {
  232. jassert (isPositiveAndBelow (channel, numChannels));
  233. jassert (isPositiveAndBelow (index, size));
  234. return *(channels [channel] + index);
  235. }
  236. void AudioSampleBuffer::setSample (int channel, int index, float newValue) noexcept
  237. {
  238. jassert (isPositiveAndBelow (channel, numChannels));
  239. jassert (isPositiveAndBelow (index, size));
  240. *(channels [channel] + index) = newValue;
  241. isClear = false;
  242. }
  243. void AudioSampleBuffer::addSample (int channel, int index, float valueToAdd) noexcept
  244. {
  245. jassert (isPositiveAndBelow (channel, numChannels));
  246. jassert (isPositiveAndBelow (index, size));
  247. *(channels [channel] + index) += valueToAdd;
  248. isClear = false;
  249. }
  250. void AudioSampleBuffer::applyGain (const int channel,
  251. const int startSample,
  252. int numSamples,
  253. const float gain) noexcept
  254. {
  255. jassert (isPositiveAndBelow (channel, numChannels));
  256. jassert (startSample >= 0 && startSample + numSamples <= size);
  257. if (gain != 1.0f && ! isClear)
  258. {
  259. float* const d = channels [channel] + startSample;
  260. if (gain == 0.0f)
  261. FloatVectorOperations::clear (d, numSamples);
  262. else
  263. FloatVectorOperations::multiply (d, gain, numSamples);
  264. }
  265. }
  266. void AudioSampleBuffer::applyGainRamp (const int channel,
  267. const int startSample,
  268. int numSamples,
  269. float startGain,
  270. float endGain) noexcept
  271. {
  272. if (! isClear)
  273. {
  274. if (startGain == endGain)
  275. {
  276. applyGain (channel, startSample, numSamples, startGain);
  277. }
  278. else
  279. {
  280. jassert (isPositiveAndBelow (channel, numChannels));
  281. jassert (startSample >= 0 && startSample + numSamples <= size);
  282. const float increment = (endGain - startGain) / numSamples;
  283. float* d = channels [channel] + startSample;
  284. while (--numSamples >= 0)
  285. {
  286. *d++ *= startGain;
  287. startGain += increment;
  288. }
  289. }
  290. }
  291. }
  292. void AudioSampleBuffer::applyGain (int startSample, int numSamples, float gain) noexcept
  293. {
  294. for (int i = 0; i < numChannels; ++i)
  295. applyGain (i, startSample, numSamples, gain);
  296. }
  297. void AudioSampleBuffer::applyGain (const float gain) noexcept
  298. {
  299. applyGain (0, size, gain);
  300. }
  301. void AudioSampleBuffer::applyGainRamp (int startSample, int numSamples,
  302. float startGain, float endGain) noexcept
  303. {
  304. for (int i = 0; i < numChannels; ++i)
  305. applyGainRamp (i, startSample, numSamples, startGain, endGain);
  306. }
  307. void AudioSampleBuffer::addFrom (const int destChannel,
  308. const int destStartSample,
  309. const AudioSampleBuffer& source,
  310. const int sourceChannel,
  311. const int sourceStartSample,
  312. int numSamples,
  313. const float gain) noexcept
  314. {
  315. jassert (&source != this || sourceChannel != destChannel);
  316. jassert (isPositiveAndBelow (destChannel, numChannels));
  317. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  318. jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
  319. jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
  320. if (gain != 0.0f && numSamples > 0 && ! source.isClear)
  321. {
  322. float* const d = channels [destChannel] + destStartSample;
  323. const float* const s = source.channels [sourceChannel] + sourceStartSample;
  324. if (isClear)
  325. {
  326. isClear = false;
  327. if (gain != 1.0f)
  328. FloatVectorOperations::copyWithMultiply (d, s, gain, numSamples);
  329. else
  330. FloatVectorOperations::copy (d, s, numSamples);
  331. }
  332. else
  333. {
  334. if (gain != 1.0f)
  335. FloatVectorOperations::addWithMultiply (d, s, gain, numSamples);
  336. else
  337. FloatVectorOperations::add (d, s, numSamples);
  338. }
  339. }
  340. }
  341. void AudioSampleBuffer::addFrom (const int destChannel,
  342. const int destStartSample,
  343. const float* source,
  344. int numSamples,
  345. const float gain) noexcept
  346. {
  347. jassert (isPositiveAndBelow (destChannel, numChannels));
  348. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  349. jassert (source != nullptr);
  350. if (gain != 0.0f && numSamples > 0)
  351. {
  352. float* const d = channels [destChannel] + destStartSample;
  353. if (isClear)
  354. {
  355. isClear = false;
  356. if (gain != 1.0f)
  357. FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples);
  358. else
  359. FloatVectorOperations::copy (d, source, numSamples);
  360. }
  361. else
  362. {
  363. if (gain != 1.0f)
  364. FloatVectorOperations::addWithMultiply (d, source, gain, numSamples);
  365. else
  366. FloatVectorOperations::add (d, source, numSamples);
  367. }
  368. }
  369. }
  370. void AudioSampleBuffer::addFromWithRamp (const int destChannel,
  371. const int destStartSample,
  372. const float* source,
  373. int numSamples,
  374. float startGain,
  375. const float endGain) noexcept
  376. {
  377. jassert (isPositiveAndBelow (destChannel, numChannels));
  378. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  379. jassert (source != nullptr);
  380. if (startGain == endGain)
  381. {
  382. addFrom (destChannel, destStartSample, source, numSamples, startGain);
  383. }
  384. else
  385. {
  386. if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f))
  387. {
  388. isClear = false;
  389. const float increment = (endGain - startGain) / numSamples;
  390. float* d = channels [destChannel] + destStartSample;
  391. while (--numSamples >= 0)
  392. {
  393. *d++ += startGain * *source++;
  394. startGain += increment;
  395. }
  396. }
  397. }
  398. }
  399. void AudioSampleBuffer::copyFrom (const int destChannel,
  400. const int destStartSample,
  401. const AudioSampleBuffer& source,
  402. const int sourceChannel,
  403. const int sourceStartSample,
  404. int numSamples) noexcept
  405. {
  406. jassert (&source != this || sourceChannel != destChannel);
  407. jassert (isPositiveAndBelow (destChannel, numChannels));
  408. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  409. jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
  410. jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
  411. if (numSamples > 0)
  412. {
  413. if (source.isClear)
  414. {
  415. if (! isClear)
  416. FloatVectorOperations::clear (channels [destChannel] + destStartSample, numSamples);
  417. }
  418. else
  419. {
  420. isClear = false;
  421. FloatVectorOperations::copy (channels [destChannel] + destStartSample,
  422. source.channels [sourceChannel] + sourceStartSample,
  423. numSamples);
  424. }
  425. }
  426. }
  427. void AudioSampleBuffer::copyFrom (const int destChannel,
  428. const int destStartSample,
  429. const float* source,
  430. int numSamples) noexcept
  431. {
  432. jassert (isPositiveAndBelow (destChannel, numChannels));
  433. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  434. jassert (source != nullptr);
  435. if (numSamples > 0)
  436. {
  437. isClear = false;
  438. FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples);
  439. }
  440. }
  441. void AudioSampleBuffer::copyFrom (const int destChannel,
  442. const int destStartSample,
  443. const float* source,
  444. int numSamples,
  445. const float gain) noexcept
  446. {
  447. jassert (isPositiveAndBelow (destChannel, numChannels));
  448. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  449. jassert (source != nullptr);
  450. if (numSamples > 0)
  451. {
  452. float* const d = channels [destChannel] + destStartSample;
  453. if (gain != 1.0f)
  454. {
  455. if (gain == 0)
  456. {
  457. if (! isClear)
  458. FloatVectorOperations::clear (d, numSamples);
  459. }
  460. else
  461. {
  462. isClear = false;
  463. FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples);
  464. }
  465. }
  466. else
  467. {
  468. isClear = false;
  469. FloatVectorOperations::copy (d, source, numSamples);
  470. }
  471. }
  472. }
  473. void AudioSampleBuffer::copyFromWithRamp (const int destChannel,
  474. const int destStartSample,
  475. const float* source,
  476. int numSamples,
  477. float startGain,
  478. float endGain) noexcept
  479. {
  480. jassert (isPositiveAndBelow (destChannel, numChannels));
  481. jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
  482. jassert (source != nullptr);
  483. if (startGain == endGain)
  484. {
  485. copyFrom (destChannel, destStartSample, source, numSamples, startGain);
  486. }
  487. else
  488. {
  489. if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f))
  490. {
  491. isClear = false;
  492. const float increment = (endGain - startGain) / numSamples;
  493. float* d = channels [destChannel] + destStartSample;
  494. while (--numSamples >= 0)
  495. {
  496. *d++ = startGain * *source++;
  497. startGain += increment;
  498. }
  499. }
  500. }
  501. }
  502. void AudioSampleBuffer::reverse (int channel, int startSample, int numSamples) const noexcept
  503. {
  504. jassert (isPositiveAndBelow (channel, numChannels));
  505. jassert (startSample >= 0 && startSample + numSamples <= size);
  506. if (! isClear)
  507. std::reverse (channels[channel] + startSample,
  508. channels[channel] + startSample + numSamples);
  509. }
  510. void AudioSampleBuffer::reverse (int startSample, int numSamples) const noexcept
  511. {
  512. for (int i = 0; i < numChannels; ++i)
  513. reverse (i, startSample, numSamples);
  514. }
  515. Range<float> AudioSampleBuffer::findMinMax (const int channel,
  516. const int startSample,
  517. int numSamples) const noexcept
  518. {
  519. jassert (isPositiveAndBelow (channel, numChannels));
  520. jassert (startSample >= 0 && startSample + numSamples <= size);
  521. if (isClear)
  522. return Range<float>();
  523. return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples);
  524. }
  525. float AudioSampleBuffer::getMagnitude (const int channel,
  526. const int startSample,
  527. const int numSamples) const noexcept
  528. {
  529. jassert (isPositiveAndBelow (channel, numChannels));
  530. jassert (startSample >= 0 && startSample + numSamples <= size);
  531. if (isClear)
  532. return 0.0f;
  533. const Range<float> r (findMinMax (channel, startSample, numSamples));
  534. return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd());
  535. }
  536. float AudioSampleBuffer::getMagnitude (int startSample, int numSamples) const noexcept
  537. {
  538. float mag = 0.0f;
  539. if (! isClear)
  540. for (int i = 0; i < numChannels; ++i)
  541. mag = jmax (mag, getMagnitude (i, startSample, numSamples));
  542. return mag;
  543. }
  544. float AudioSampleBuffer::getRMSLevel (const int channel,
  545. const int startSample,
  546. const int numSamples) const noexcept
  547. {
  548. jassert (isPositiveAndBelow (channel, numChannels));
  549. jassert (startSample >= 0 && startSample + numSamples <= size);
  550. if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear)
  551. return 0.0f;
  552. const float* const data = channels [channel] + startSample;
  553. double sum = 0.0;
  554. for (int i = 0; i < numSamples; ++i)
  555. {
  556. const float sample = data [i];
  557. sum += sample * sample;
  558. }
  559. return (float) std::sqrt (sum / numSamples);
  560. }