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.

557 lines
17KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 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. #include "../../core/juce_StandardHeader.h"
  19. BEGIN_JUCE_NAMESPACE
  20. #include "juce_AudioFormat.h"
  21. #include "../dsp/juce_AudioSampleBuffer.h"
  22. //==============================================================================
  23. AudioFormatReader::AudioFormatReader (InputStream* const in,
  24. const String& formatName_)
  25. : sampleRate (0),
  26. bitsPerSample (0),
  27. lengthInSamples (0),
  28. numChannels (0),
  29. usesFloatingPointData (false),
  30. input (in),
  31. formatName (formatName_)
  32. {
  33. }
  34. AudioFormatReader::~AudioFormatReader()
  35. {
  36. delete input;
  37. }
  38. bool AudioFormatReader::read (int** destSamples,
  39. int numDestChannels,
  40. int64 startSampleInSource,
  41. int numSamplesToRead,
  42. const bool fillLeftoverChannelsWithCopies)
  43. {
  44. jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
  45. int startOffsetInDestBuffer = 0;
  46. if (startSampleInSource < 0)
  47. {
  48. const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
  49. for (int i = numDestChannels; --i >= 0;)
  50. if (destSamples[i] != 0)
  51. zeromem (destSamples[i], sizeof (int) * silence);
  52. startOffsetInDestBuffer += silence;
  53. numSamplesToRead -= silence;
  54. startSampleInSource = 0;
  55. }
  56. if (numSamplesToRead <= 0)
  57. return true;
  58. if (! readSamples (destSamples, jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
  59. startSampleInSource, numSamplesToRead))
  60. return false;
  61. if (numDestChannels > (int) numChannels)
  62. {
  63. if (fillLeftoverChannelsWithCopies)
  64. {
  65. int* lastFullChannel = destSamples[0];
  66. for (int i = numDestChannels; --i > 0;)
  67. {
  68. if (destSamples[i] != 0)
  69. {
  70. lastFullChannel = destSamples[i];
  71. break;
  72. }
  73. }
  74. if (lastFullChannel != 0)
  75. for (int i = numChannels; i < numDestChannels; ++i)
  76. if (destSamples[i] != 0)
  77. memcpy (destSamples[i], lastFullChannel, sizeof (int) * numSamplesToRead);
  78. }
  79. else
  80. {
  81. for (int i = numChannels; i < numDestChannels; ++i)
  82. if (destSamples[i] != 0)
  83. zeromem (destSamples[i], sizeof (int) * numSamplesToRead);
  84. }
  85. }
  86. return true;
  87. }
  88. static void findAudioBufferMaxMin (const float* const buffer, const int num, float& maxVal, float& minVal) throw()
  89. {
  90. float mn = buffer[0];
  91. float mx = mn;
  92. for (int i = 1; i < num; ++i)
  93. {
  94. const float s = buffer[i];
  95. if (s > mx) mx = s;
  96. if (s < mn) mn = s;
  97. }
  98. maxVal = mx;
  99. minVal = mn;
  100. }
  101. void AudioFormatReader::readMaxLevels (int64 startSampleInFile,
  102. int64 numSamples,
  103. float& lowestLeft, float& highestLeft,
  104. float& lowestRight, float& highestRight)
  105. {
  106. if (numSamples <= 0)
  107. {
  108. lowestLeft = 0;
  109. lowestRight = 0;
  110. highestLeft = 0;
  111. highestRight = 0;
  112. return;
  113. }
  114. const int bufferSize = (int) jmin (numSamples, (int64) 4096);
  115. MemoryBlock tempSpace (bufferSize * sizeof (int) * 2 + 64);
  116. int* tempBuffer[3];
  117. tempBuffer[0] = (int*) tempSpace.getData();
  118. tempBuffer[1] = ((int*) tempSpace.getData()) + bufferSize;
  119. tempBuffer[2] = 0;
  120. if (usesFloatingPointData)
  121. {
  122. float lmin = 1.0e6f;
  123. float lmax = -lmin;
  124. float rmin = lmin;
  125. float rmax = lmax;
  126. while (numSamples > 0)
  127. {
  128. const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
  129. read ((int**) tempBuffer, 2, startSampleInFile, numToDo, false);
  130. numSamples -= numToDo;
  131. startSampleInFile += numToDo;
  132. float bufmin, bufmax;
  133. findAudioBufferMaxMin ((float*) tempBuffer[0], numToDo, bufmax, bufmin);
  134. lmin = jmin (lmin, bufmin);
  135. lmax = jmax (lmax, bufmax);
  136. if (numChannels > 1)
  137. {
  138. findAudioBufferMaxMin ((float*) tempBuffer[1], numToDo, bufmax, bufmin);
  139. rmin = jmin (rmin, bufmin);
  140. rmax = jmax (rmax, bufmax);
  141. }
  142. }
  143. if (numChannels <= 1)
  144. {
  145. rmax = lmax;
  146. rmin = lmin;
  147. }
  148. lowestLeft = lmin;
  149. highestLeft = lmax;
  150. lowestRight = rmin;
  151. highestRight = rmax;
  152. }
  153. else
  154. {
  155. int lmax = std::numeric_limits<int>::min();
  156. int lmin = std::numeric_limits<int>::max();
  157. int rmax = std::numeric_limits<int>::min();
  158. int rmin = std::numeric_limits<int>::max();
  159. while (numSamples > 0)
  160. {
  161. const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
  162. read ((int**) tempBuffer, 2, startSampleInFile, numToDo, false);
  163. numSamples -= numToDo;
  164. startSampleInFile += numToDo;
  165. for (int j = numChannels; --j >= 0;)
  166. {
  167. int bufMax = std::numeric_limits<int>::min();
  168. int bufMin = std::numeric_limits<int>::max();
  169. const int* const b = tempBuffer[j];
  170. for (int i = 0; i < numToDo; ++i)
  171. {
  172. const int samp = b[i];
  173. if (samp < bufMin)
  174. bufMin = samp;
  175. if (samp > bufMax)
  176. bufMax = samp;
  177. }
  178. if (j == 0)
  179. {
  180. lmax = jmax (lmax, bufMax);
  181. lmin = jmin (lmin, bufMin);
  182. }
  183. else
  184. {
  185. rmax = jmax (rmax, bufMax);
  186. rmin = jmin (rmin, bufMin);
  187. }
  188. }
  189. }
  190. if (numChannels <= 1)
  191. {
  192. rmax = lmax;
  193. rmin = lmin;
  194. }
  195. lowestLeft = lmin / (float) std::numeric_limits<int>::max();
  196. highestLeft = lmax / (float) std::numeric_limits<int>::max();
  197. lowestRight = rmin / (float) std::numeric_limits<int>::max();
  198. highestRight = rmax / (float) std::numeric_limits<int>::max();
  199. }
  200. }
  201. int64 AudioFormatReader::searchForLevel (int64 startSample,
  202. int64 numSamplesToSearch,
  203. const double magnitudeRangeMinimum,
  204. const double magnitudeRangeMaximum,
  205. const int minimumConsecutiveSamples)
  206. {
  207. if (numSamplesToSearch == 0)
  208. return -1;
  209. const int bufferSize = 4096;
  210. MemoryBlock tempSpace (bufferSize * sizeof (int) * 2 + 64);
  211. int* tempBuffer[3];
  212. tempBuffer[0] = (int*) tempSpace.getData();
  213. tempBuffer[1] = ((int*) tempSpace.getData()) + bufferSize;
  214. tempBuffer[2] = 0;
  215. int consecutive = 0;
  216. int64 firstMatchPos = -1;
  217. jassert (magnitudeRangeMaximum > magnitudeRangeMinimum);
  218. const double doubleMin = jlimit (0.0, (double) std::numeric_limits<int>::max(), magnitudeRangeMinimum * std::numeric_limits<int>::max());
  219. const double doubleMax = jlimit (doubleMin, (double) std::numeric_limits<int>::max(), magnitudeRangeMaximum * std::numeric_limits<int>::max());
  220. const int intMagnitudeRangeMinimum = roundToInt (doubleMin);
  221. const int intMagnitudeRangeMaximum = roundToInt (doubleMax);
  222. while (numSamplesToSearch != 0)
  223. {
  224. const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize);
  225. int64 bufferStart = startSample;
  226. if (numSamplesToSearch < 0)
  227. bufferStart -= numThisTime;
  228. if (bufferStart >= (int) lengthInSamples)
  229. break;
  230. read ((int**) tempBuffer, 2, bufferStart, numThisTime, false);
  231. int num = numThisTime;
  232. while (--num >= 0)
  233. {
  234. if (numSamplesToSearch < 0)
  235. --startSample;
  236. bool matches = false;
  237. const int index = (int) (startSample - bufferStart);
  238. if (usesFloatingPointData)
  239. {
  240. const float sample1 = fabsf (((float*) tempBuffer[0]) [index]);
  241. if (sample1 >= magnitudeRangeMinimum
  242. && sample1 <= magnitudeRangeMaximum)
  243. {
  244. matches = true;
  245. }
  246. else if (numChannels > 1)
  247. {
  248. const float sample2 = fabsf (((float*) tempBuffer[1]) [index]);
  249. matches = (sample2 >= magnitudeRangeMinimum
  250. && sample2 <= magnitudeRangeMaximum);
  251. }
  252. }
  253. else
  254. {
  255. const int sample1 = abs (tempBuffer[0] [index]);
  256. if (sample1 >= intMagnitudeRangeMinimum
  257. && sample1 <= intMagnitudeRangeMaximum)
  258. {
  259. matches = true;
  260. }
  261. else if (numChannels > 1)
  262. {
  263. const int sample2 = abs (tempBuffer[1][index]);
  264. matches = (sample2 >= intMagnitudeRangeMinimum
  265. && sample2 <= intMagnitudeRangeMaximum);
  266. }
  267. }
  268. if (matches)
  269. {
  270. if (firstMatchPos < 0)
  271. firstMatchPos = startSample;
  272. if (++consecutive >= minimumConsecutiveSamples)
  273. {
  274. if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples)
  275. return -1;
  276. return firstMatchPos;
  277. }
  278. }
  279. else
  280. {
  281. consecutive = 0;
  282. firstMatchPos = -1;
  283. }
  284. if (numSamplesToSearch > 0)
  285. ++startSample;
  286. }
  287. if (numSamplesToSearch > 0)
  288. numSamplesToSearch -= numThisTime;
  289. else
  290. numSamplesToSearch += numThisTime;
  291. }
  292. return -1;
  293. }
  294. //==============================================================================
  295. AudioFormatWriter::AudioFormatWriter (OutputStream* const out,
  296. const String& formatName_,
  297. const double rate,
  298. const unsigned int numChannels_,
  299. const unsigned int bitsPerSample_)
  300. : sampleRate (rate),
  301. numChannels (numChannels_),
  302. bitsPerSample (bitsPerSample_),
  303. usesFloatingPointData (false),
  304. output (out),
  305. formatName (formatName_)
  306. {
  307. }
  308. AudioFormatWriter::~AudioFormatWriter()
  309. {
  310. delete output;
  311. }
  312. bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
  313. int64 startSample,
  314. int64 numSamplesToRead)
  315. {
  316. const int bufferSize = 16384;
  317. const int maxChans = 128;
  318. AudioSampleBuffer tempBuffer (reader.numChannels, bufferSize);
  319. int* buffers [maxChans];
  320. for (int i = maxChans; --i >= 0;)
  321. buffers[i] = 0;
  322. if (numSamplesToRead < 0)
  323. numSamplesToRead = reader.lengthInSamples;
  324. while (numSamplesToRead > 0)
  325. {
  326. const int numToDo = (int) jmin (numSamplesToRead, (int64) bufferSize);
  327. for (int i = tempBuffer.getNumChannels(); --i >= 0;)
  328. buffers[i] = (int*) tempBuffer.getSampleData (i, 0);
  329. if (! reader.read (buffers, maxChans, startSample, numToDo, false))
  330. return false;
  331. if (reader.usesFloatingPointData != isFloatingPoint())
  332. {
  333. int** bufferChan = buffers;
  334. while (*bufferChan != 0)
  335. {
  336. int* b = *bufferChan++;
  337. if (isFloatingPoint())
  338. {
  339. // int -> float
  340. const double factor = 1.0 / std::numeric_limits<int>::max();
  341. for (int i = 0; i < numToDo; ++i)
  342. ((float*) b)[i] = (float) (factor * b[i]);
  343. }
  344. else
  345. {
  346. // float -> int
  347. for (int i = 0; i < numToDo; ++i)
  348. {
  349. const double samp = *(const float*) b;
  350. if (samp <= -1.0)
  351. *b++ = std::numeric_limits<int>::min();
  352. else if (samp >= 1.0)
  353. *b++ = std::numeric_limits<int>::max();
  354. else
  355. *b++ = roundToInt (std::numeric_limits<int>::max() * samp);
  356. }
  357. }
  358. }
  359. }
  360. if (! write ((const int**) buffers, numToDo))
  361. return false;
  362. numSamplesToRead -= numToDo;
  363. startSample += numToDo;
  364. }
  365. return true;
  366. }
  367. bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,
  368. int numSamplesToRead,
  369. const int samplesPerBlock)
  370. {
  371. const int maxChans = 128;
  372. AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock);
  373. int* buffers [maxChans];
  374. while (numSamplesToRead > 0)
  375. {
  376. const int numToDo = jmin (numSamplesToRead, samplesPerBlock);
  377. AudioSourceChannelInfo info;
  378. info.buffer = &tempBuffer;
  379. info.startSample = 0;
  380. info.numSamples = numToDo;
  381. info.clearActiveBufferRegion();
  382. source.getNextAudioBlock (info);
  383. int i;
  384. for (i = maxChans; --i >= 0;)
  385. buffers[i] = 0;
  386. for (i = tempBuffer.getNumChannels(); --i >= 0;)
  387. buffers[i] = (int*) tempBuffer.getSampleData (i, 0);
  388. if (! isFloatingPoint())
  389. {
  390. int** bufferChan = buffers;
  391. while (*bufferChan != 0)
  392. {
  393. int* b = *bufferChan++;
  394. // float -> int
  395. for (int j = numToDo; --j >= 0;)
  396. {
  397. const double samp = *(const float*) b;
  398. if (samp <= -1.0)
  399. *b++ = std::numeric_limits<int>::min();
  400. else if (samp >= 1.0)
  401. *b++ = std::numeric_limits<int>::max();
  402. else
  403. *b++ = roundToInt (std::numeric_limits<int>::max() * samp);
  404. }
  405. }
  406. }
  407. if (! write ((const int**) buffers, numToDo))
  408. return false;
  409. numSamplesToRead -= numToDo;
  410. }
  411. return true;
  412. }
  413. //==============================================================================
  414. AudioFormat::AudioFormat (const String& name,
  415. const tchar** const extensions)
  416. : formatName (name),
  417. fileExtensions (extensions)
  418. {
  419. }
  420. AudioFormat::~AudioFormat()
  421. {
  422. }
  423. //==============================================================================
  424. const String& AudioFormat::getFormatName() const
  425. {
  426. return formatName;
  427. }
  428. const StringArray& AudioFormat::getFileExtensions() const
  429. {
  430. return fileExtensions;
  431. }
  432. bool AudioFormat::canHandleFile (const File& f)
  433. {
  434. for (int i = 0; i < fileExtensions.size(); ++i)
  435. if (f.hasFileExtension (fileExtensions[i]))
  436. return true;
  437. return false;
  438. }
  439. bool AudioFormat::isCompressed()
  440. {
  441. return false;
  442. }
  443. const StringArray AudioFormat::getQualityOptions()
  444. {
  445. return StringArray();
  446. }
  447. END_JUCE_NAMESPACE