The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

566 lines
19KB

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