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.

juce_AudioSampleBuffer.cpp 22KB

9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  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. }