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.

674 lines
22KB

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