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.

192 lines
6.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the Water library.
  4. Copyright (c) 2015 ROLI Ltd.
  5. Copyright (C) 2018 Filipe Coelho <falktx@falktx.com>
  6. Permission is granted to use this software under the terms of either:
  7. a) the GPL v2 (or any later version)
  8. b) the Affero GPL v3
  9. Details of these licenses can be found at: www.gnu.org/licenses
  10. Water 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. */
  15. #include "AudioFormatReader.h"
  16. #include "../buffers/AudioSampleBuffer.h"
  17. #include "../streams/InputStream.h"
  18. namespace water {
  19. AudioFormatReader::AudioFormatReader (InputStream* const in, const String& name)
  20. : sampleRate (0),
  21. bitsPerSample (0),
  22. lengthInSamples (0),
  23. numChannels (0),
  24. usesFloatingPointData (false),
  25. input (in),
  26. formatName (name)
  27. {
  28. }
  29. AudioFormatReader::~AudioFormatReader()
  30. {
  31. delete input;
  32. }
  33. bool AudioFormatReader::read (int* const* destSamples,
  34. int numDestChannels,
  35. int64 startSampleInSource,
  36. int numSamplesToRead,
  37. const bool fillLeftoverChannelsWithCopies)
  38. {
  39. jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
  40. const size_t originalNumSamplesToRead = (size_t) numSamplesToRead;
  41. int startOffsetInDestBuffer = 0;
  42. if (startSampleInSource < 0)
  43. {
  44. const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
  45. for (int i = numDestChannels; --i >= 0;)
  46. if (destSamples[i] != nullptr)
  47. zeromem (destSamples[i], sizeof (int) * (size_t) silence);
  48. startOffsetInDestBuffer += silence;
  49. numSamplesToRead -= silence;
  50. startSampleInSource = 0;
  51. }
  52. if (numSamplesToRead <= 0)
  53. return true;
  54. if (! readSamples (const_cast<int**> (destSamples),
  55. jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
  56. startSampleInSource, numSamplesToRead))
  57. return false;
  58. if (numDestChannels > (int) numChannels)
  59. {
  60. if (fillLeftoverChannelsWithCopies)
  61. {
  62. int* lastFullChannel = destSamples[0];
  63. for (int i = (int) numChannels; --i > 0;)
  64. {
  65. if (destSamples[i] != nullptr)
  66. {
  67. lastFullChannel = destSamples[i];
  68. break;
  69. }
  70. }
  71. if (lastFullChannel != nullptr)
  72. for (int i = (int) numChannels; i < numDestChannels; ++i)
  73. if (destSamples[i] != nullptr)
  74. memcpy (destSamples[i], lastFullChannel, sizeof (int) * originalNumSamplesToRead);
  75. }
  76. else
  77. {
  78. for (int i = (int) numChannels; i < numDestChannels; ++i)
  79. if (destSamples[i] != nullptr)
  80. zeromem (destSamples[i], sizeof (int) * originalNumSamplesToRead);
  81. }
  82. }
  83. return true;
  84. }
  85. static void readChannels (AudioFormatReader& reader,
  86. int** const chans, AudioSampleBuffer* const buffer,
  87. const int startSample, const int numSamples,
  88. const int64 readerStartSample, const int numTargetChannels)
  89. {
  90. for (int j = 0; j < numTargetChannels; ++j)
  91. chans[j] = reinterpret_cast<int*> (buffer->getWritePointer (j, startSample));
  92. chans[numTargetChannels] = nullptr;
  93. reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
  94. }
  95. #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \
  96. for (int i = 0; i < num; ++i) normalOp;
  97. static void convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept
  98. {
  99. for (int i = 0; i < num; ++i)
  100. dest[i] = src[i] * multiplier;
  101. }
  102. void AudioFormatReader::read (AudioSampleBuffer* buffer,
  103. int startSample,
  104. int numSamples,
  105. int64 readerStartSample,
  106. bool useReaderLeftChan,
  107. bool useReaderRightChan)
  108. {
  109. jassert (buffer != nullptr);
  110. jassert (startSample >= 0 && startSample + numSamples <= buffer->getNumSamples());
  111. if (numSamples > 0)
  112. {
  113. const int numTargetChannels = buffer->getNumChannels();
  114. if (numTargetChannels <= 2)
  115. {
  116. int* const dest0 = reinterpret_cast<int*> (buffer->getWritePointer (0, startSample));
  117. int* const dest1 = reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr);
  118. int* chans[3];
  119. if (useReaderLeftChan == useReaderRightChan)
  120. {
  121. chans[0] = dest0;
  122. chans[1] = numChannels > 1 ? dest1 : nullptr;
  123. }
  124. else if (useReaderLeftChan || (numChannels == 1))
  125. {
  126. chans[0] = dest0;
  127. chans[1] = nullptr;
  128. }
  129. else if (useReaderRightChan)
  130. {
  131. chans[0] = nullptr;
  132. chans[1] = dest0;
  133. }
  134. chans[2] = nullptr;
  135. read (chans, 2, readerStartSample, numSamples, true);
  136. // if the target's stereo and the source is mono, dupe the first channel..
  137. if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr))
  138. memcpy (dest1, dest0, sizeof (float) * (size_t) numSamples);
  139. }
  140. else if (numTargetChannels <= 64)
  141. {
  142. int* chans[65];
  143. readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
  144. }
  145. else
  146. {
  147. HeapBlock<int*> chans;
  148. chans.malloc ((size_t) numTargetChannels + 1);
  149. // FIXME, check malloc return
  150. readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
  151. }
  152. if (! usesFloatingPointData)
  153. for (int j = 0; j < numTargetChannels; ++j)
  154. if (float* const d = buffer->getWritePointer (j, startSample))
  155. convertFixedToFloat (d, reinterpret_cast<const int*> (d), 1.0f / 0x7fffffff, numSamples);
  156. }
  157. }
  158. }