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

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