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