Browse Source

Update juce (no patches)

tags/2018-04-16
falkTX 10 years ago
parent
commit
794896deb2
100 changed files with 3026 additions and 2526 deletions
  1. +2
    -2
      .gitignore
  2. +0
    -16
      libs/juce/patches/linux-vst-reparent.patch
  3. +12
    -0
      libs/juce/patches/vst3-less-strict.patch
  4. +6
    -0
      libs/juce/source/README.txt
  5. +22
    -20
      libs/juce/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h
  6. +154
    -4
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  7. +36
    -0
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
  8. +277
    -0
      libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.cpp
  9. +92
    -0
      libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.h
  10. +3
    -3
      libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp
  11. +0
    -239
      libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp
  12. +0
    -148
      libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h
  13. +8
    -2
      libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp
  14. +92
    -43
      libs/juce/source/modules/juce_audio_basics/effects/juce_Reverb.h
  15. +1
    -1
      libs/juce/source/modules/juce_audio_basics/juce_audio_basics.cpp
  16. +4
    -1
      libs/juce/source/modules/juce_audio_basics/juce_audio_basics.h
  17. +1
    -1
      libs/juce/source/modules/juce_audio_basics/juce_module_info
  18. +15
    -21
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp
  19. +1
    -1
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h
  20. +9
    -7
      libs/juce/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp
  21. +21
    -13
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  22. +13
    -7
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  23. +18
    -13
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  24. +0
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h
  25. +1
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp
  26. +1
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h
  27. +1
    -1
      libs/juce/source/modules/juce_audio_devices/juce_audio_devices.cpp
  28. +10
    -1
      libs/juce/source/modules/juce_audio_devices/juce_audio_devices.h
  29. +1
    -1
      libs/juce/source/modules/juce_audio_devices/juce_module_info
  30. +6
    -8
      libs/juce/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h
  31. +12
    -17
      libs/juce/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h
  32. +6
    -6
      libs/juce/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp
  33. +21
    -7
      libs/juce/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp
  34. +12
    -3
      libs/juce/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp
  35. +1
    -1
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  36. +65
    -49
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp
  37. +1
    -1
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp
  38. +324
    -140
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp
  39. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/all.h
  40. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/alloc.h
  41. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/assert.h
  42. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/callback.h
  43. +20
    -15
      libs/juce/source/modules/juce_audio_formats/codecs/flac/compat.h
  44. +28
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/endswap.h
  45. +3
    -3
      libs/juce/source/modules/juce_audio_formats/codecs/flac/export.h
  46. +4
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/format.h
  47. +2
    -3
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c
  48. +6
    -10
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c
  49. +5
    -31
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c
  50. +338
    -267
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c
  51. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c
  52. +3
    -16
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c
  53. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/float.c
  54. +3
    -8
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/format.c
  55. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h
  56. +48
    -33
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h
  57. +2
    -11
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h
  58. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h
  59. +31
    -21
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h
  60. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h
  61. +14
    -5
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h
  62. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h
  63. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h
  64. +37
    -6
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h
  65. +7
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h
  66. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h
  67. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h
  68. +67
    -0
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h
  69. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h
  70. +3
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h
  71. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h
  72. +2
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h
  73. +8
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h
  74. +17
    -13
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c
  75. +203
    -106
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c
  76. +8
    -21
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c
  77. +123
    -100
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c
  78. +245
    -54
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c
  79. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c
  80. +68
    -13
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c
  81. +2
    -2
      libs/juce/source/modules/juce_audio_formats/codecs/flac/metadata.h
  82. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/ordinals.h
  83. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/stream_decoder.h
  84. +45
    -24
      libs/juce/source/modules/juce_audio_formats/codecs/flac/stream_encoder.h
  85. +69
    -0
      libs/juce/source/modules/juce_audio_formats/codecs/flac/win_utf8_io.h
  86. +118
    -56
      libs/juce/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp
  87. +9
    -9
      libs/juce/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp
  88. +41
    -17
      libs/juce/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
  89. +13
    -11
      libs/juce/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp
  90. +3
    -3
      libs/juce/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h
  91. +2
    -9
      libs/juce/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp
  92. +1
    -2
      libs/juce/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h
  93. +9
    -3
      libs/juce/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h
  94. +1
    -1
      libs/juce/source/modules/juce_audio_formats/juce_module_info
  95. +1
    -1
      libs/juce/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp
  96. +14
    -4
      libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
  97. +131
    -62
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  98. +0
    -83
      libs/juce/source/modules/juce_audio_plugin_client/LV2/base64/Base64.cpp
  99. +0
    -446
      libs/juce/source/modules/juce_audio_plugin_client/LV2/includes/atom-util.h
  100. +0
    -246
      libs/juce/source/modules/juce_audio_plugin_client/LV2/includes/atom.h

+ 2
- 2
.gitignore View File

@@ -38,8 +38,10 @@ _old
ports/_todo

libs/juce/source/.gitignore
libs/juce/source/ChangeList.txt
libs/juce/source/amalgamation/
libs/juce/source/docs/
libs/juce/source/examples/
libs/juce/source/extras/
libs/juce/source/juce.h
libs/juce/source/juce_amalgamated.cpp
@@ -47,7 +49,5 @@ libs/juce/source/juce_amalgamated.h
libs/juce/source/juce_amalgamated.mm
libs/juce/source/modules/juce_box2d/
libs/juce/source/modules/juce_browser_plugin_client/
libs/juce/source/modules/juce_cryptography/
libs/juce/source/modules/juce_opengl/
libs/juce/source/modules/juce_tracktion_marketplace/
libs/juce/source/modules/juce_video/

+ 0
- 16
libs/juce/patches/linux-vst-reparent.patch View File

@@ -1,16 +0,0 @@
diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
index b88a3b2..d057fb0 100644
--- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
+++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
@@ -1180,8 +1180,10 @@ public:
editorComp->addToDesktop (0, ptr);
hostWindow = (HWND) ptr;
#elif JUCE_LINUX
- editorComp->addToDesktop (0, ptr);
+ editorComp->addToDesktop (0);
hostWindow = (Window) ptr;
+ Window editorWnd = (Window) editorComp->getWindowHandle();
+ XReparentWindow (display, editorWnd, hostWindow, 0, 0);
#else
hostWindow = attachComponentToWindowRef (editorComp, ptr, useNSView);
#endif

+ 12
- 0
libs/juce/patches/vst3-less-strict.patch View File

@@ -0,0 +1,12 @@
--- a/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
+++ b/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
@@ -1403,7 +1403,8 @@ class VST3ModuleHandle : public ReferenceCountedObject
const Result result (finder.findDescriptionsAndPerform (f));
- if (result.getErrorMessage() == MatchingDescriptionFinder::getSuccessString())
+ if (result.getErrorMessage() == MatchingDescriptionFinder::getSuccessString() ||
+ result.getErrorMessage().isEmpty())
{
name = description.name;
return true;

+ 6
- 0
libs/juce/source/README.txt View File

@@ -7,5 +7,11 @@ It contains pretty much everything you're likely to need to create
most applications, and is particularly well-suited for building
highly-customised GUIs, and for handling graphics and sound.

Most JUCE modules are shared under the GNU Public Licence
(GPLv2, v3, and the AGPLv3). This means that the code can
be freely copied and distributed, and costs nothing to use
in other GPL applications. One module (the juce_core module)
is permissively licensed under the ISC.

For more information, visit the website:
http://www.juce.com

+ 22
- 20
libs/juce/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h View File

@@ -487,13 +487,10 @@ public:
}
/** Scans a block of data, returning the lowest and highest levels as floats */
void findMinAndMax (size_t numSamples, float& minValue, float& maxValue) const noexcept
Range<float> findMinAndMax (size_t numSamples) const noexcept
{
if (numSamples == 0)
{
minValue = maxValue = 0;
return;
}
return Range<float>();
Pointer dest (*this);
@@ -512,27 +509,32 @@ public:
if (v < mn) mn = v;
}
minValue = mn;
maxValue = mx;
return Range<float> (mn, mx);
}
else
int32 mn = dest.getAsInt32();
dest.advance();
int32 mx = mn;
while (--numSamples > 0)
{
int32 mn = dest.getAsInt32();
const int v = dest.getAsInt32();
dest.advance();
int32 mx = mn;
while (--numSamples > 0)
{
const int v = dest.getAsInt32();
dest.advance();
if (mx < v) mx = v;
if (v < mn) mn = v;
}
if (mx < v) mx = v;
if (v < mn) mn = v;
}
return Range<float> (mn * (float) (1.0 / (1.0 + Int32::maxValue)),
mx * (float) (1.0 / (1.0 + Int32::maxValue)));
}
minValue = mn * (float) (1.0 / (1.0 + Int32::maxValue));
maxValue = mx * (float) (1.0 / (1.0 + Int32::maxValue));
}
/** Scans a block of data, returning the lowest and highest levels as floats */
void findMinAndMax (size_t numSamples, float& minValue, float& maxValue) const noexcept
{
Range<float> r (findMinAndMax (numSamples));
minValue = r.getStart();
maxValue = r.getEnd();
}
/** Returns true if the pointer is using a floating-point format. */


+ 154
- 4
libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -134,6 +134,19 @@ namespace FloatVectorHelpers
} \
JUCE_FINISH_VEC_OP (normalOp)
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
JUCE_BEGIN_VEC_OP \
setupOp \
{ \
Mode::ParallelType (&loadSrc1) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src1) ? Mode::loadA : Mode::loadU; \
Mode::ParallelType (&loadSrc2) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src2) ? Mode::loadA : Mode::loadU; \
Mode::ParallelType (&loadDst) (const Mode::Type* v) = FloatVectorHelpers::isAligned (dest) ? Mode::loadA : Mode::loadU; \
void (&storeDst) (Mode::Type* dest, Mode::ParallelType a) = FloatVectorHelpers::isAligned (dest) ? Mode::storeA : Mode::storeU; \
JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, loadSrc1, loadSrc2, loadDst, storeDst, locals, increment); \
} \
JUCE_FINISH_VEC_OP (normalOp)
//==============================================================================
#elif JUCE_USE_ARM_NEON
@@ -211,6 +224,13 @@ namespace FloatVectorHelpers
JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
JUCE_FINISH_VEC_OP (normalOp)
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
JUCE_BEGIN_VEC_OP \
setupOp \
JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
JUCE_FINISH_VEC_OP (normalOp)
//==============================================================================
#else
#define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \
@@ -221,6 +241,10 @@ namespace FloatVectorHelpers
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
for (int i = 0; i < num; ++i) normalOp;
#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
for (int i = 0; i < num; ++i) normalOp;
#endif
//==============================================================================
@@ -240,11 +264,20 @@ namespace FloatVectorHelpers
increment; \
}
#define JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD(vecOp, src1Load, src2Load, dstLoad, dstStore, locals, increment) \
for (int i = 0; i < numLongOps; ++i) \
{ \
locals (src1Load, src2Load, dstLoad); \
dstStore (dest, vecOp); \
increment; \
}
#define JUCE_LOAD_NONE(srcLoad, dstLoad)
#define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest);
#define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src);
#define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2);
#define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src);
#define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest);
#define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src);
#define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2);
#define JUCE_LOAD_SRC1_SRC2_DEST(src1Load, src2Load, dstLoad) const Mode::ParallelType d = dstLoad (dest), s1 = src1Load (src1), s2 = src2Load (src2);
#define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src);
#if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
template<int typeSize> struct ModeType { typedef BasicOps32 Mode; };
@@ -580,6 +613,28 @@ void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const d
const Mode::ParallelType mult = Mode::load1 (multiplier);)
}
void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vma ((float*) src1, 1, (float*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], Mode::add (d, Mode::mul (s1, s2)),
JUCE_LOAD_SRC1_SRC2_DEST,
JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmaD ((double*) src1, 1, (double*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], Mode::add (d, Mode::mul (s1, s2)),
JUCE_LOAD_SRC1_SRC2_DEST,
JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
@@ -682,6 +737,96 @@ void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, cons
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::min (float* dest, const float* src, float comp, int num) noexcept
{
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), Mode::min (s, cmp),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType cmp = Mode::load1 (comp);)
}
void JUCE_CALLTYPE FloatVectorOperations::min (double* dest, const double* src, double comp, int num) noexcept
{
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), Mode::min (s, cmp),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType cmp = Mode::load1 (comp);)
}
void JUCE_CALLTYPE FloatVectorOperations::min (float* dest, const float* src1, const float* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmin ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), Mode::min (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::min (double* dest, const double* src1, const double* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vminD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), Mode::min (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::max (float* dest, const float* src, float comp, int num) noexcept
{
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), Mode::max (s, cmp),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType cmp = Mode::load1 (comp);)
}
void JUCE_CALLTYPE FloatVectorOperations::max (double* dest, const double* src, double comp, int num) noexcept
{
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), Mode::max (s, cmp),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType cmp = Mode::load1 (comp);)
}
void JUCE_CALLTYPE FloatVectorOperations::max (float* dest, const float* src1, const float* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmax ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), Mode::max (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::max (double* dest, const double* src1, const double* src2, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmaxD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), Mode::max (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, )
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::clip (float* dest, const float* src, float low, float high, int num) noexcept
{
jassert(high >= low);
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vclip ((float*) src, 1, &low, &high, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), Mode::max (Mode::min (s, hi), lo),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType lo = Mode::load1 (low); const Mode::ParallelType hi = Mode::load1 (high);)
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::clip (double* dest, const double* src, double low, double high, int num) noexcept
{
jassert(high >= low);
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vclipD ((double*) src, 1, &low, &high, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), Mode::max (Mode::min (s, hi), lo),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
const Mode::ParallelType lo = Mode::load1 (low); const Mode::ParallelType hi = Mode::load1 (high);)
#endif
}
Range<float> JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const float* src, int num) noexcept
{
#if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
@@ -823,6 +968,11 @@ public:
fillRandomly (random, int1, num);
doConversionTest (u, data1, data2, int1, num);
FloatVectorOperations::fill (data1, (ValueType) 2, num);
FloatVectorOperations::fill (data2, (ValueType) 3, num);
FloatVectorOperations::addWithMultiply (data1, data1, data2, num);
u.expect (areAllValuesEqual (data1, num, (ValueType) 8));
}
static void doConversionTest (UnitTest& u, float* data1, float* data2, int* const int1, int num)


+ 36
- 0
libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h View File

@@ -101,6 +101,12 @@ public:
/** Multiplies each source value by the given multiplier, then adds it to the destination value. */
static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept;
/** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */
static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept;
/** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */
static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept;
/** Multiplies the destination values by the source values. */
static void JUCE_CALLTYPE multiply (float* dest, const float* src, int numValues) noexcept;
@@ -134,6 +140,36 @@ public:
/** Converts a stream of integers to floats, multiplying each one by the given multiplier. */
static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int numValues) noexcept;
/** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */
static void JUCE_CALLTYPE min (float* dest, const float* src, float comp, int num) noexcept;
/** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */
static void JUCE_CALLTYPE min (double* dest, const double* src, double comp, int num) noexcept;
/** Each element of dest will be the minimum of the corresponding source1 and source2 values. */
static void JUCE_CALLTYPE min (float* dest, const float* src1, const float* src2, int num) noexcept;
/** Each element of dest will be the minimum of the corresponding source1 and source2 values. */
static void JUCE_CALLTYPE min (double* dest, const double* src1, const double* src2, int num) noexcept;
/** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */
static void JUCE_CALLTYPE max (float* dest, const float* src, float comp, int num) noexcept;
/** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */
static void JUCE_CALLTYPE max (double* dest, const double* src, double comp, int num) noexcept;
/** Each element of dest will be the maximum of the corresponding source1 and source2 values. */
static void JUCE_CALLTYPE max (float* dest, const float* src1, const float* src2, int num) noexcept;
/** Each element of dest will be the maximum of the corresponding source1 and source2 values. */
static void JUCE_CALLTYPE max (double* dest, const double* src1, const double* src2, int num) noexcept;
/** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */
static void JUCE_CALLTYPE clip (float* dest, const float* src, float low, float high, int num) noexcept;
/** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */
static void JUCE_CALLTYPE clip (double* dest, const double* src, double low, double high, int num) noexcept;
/** Finds the miniumum and maximum values in the given array. */
static Range<float> JUCE_CALLTYPE findMinAndMax (const float* src, int numValues) noexcept;


+ 277
- 0
libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.cpp View File

@@ -0,0 +1,277 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
// (For the moment, we'll implement a few local operators for this complex class - one
// day we'll probably either have a juce complex class, or use the C++11 one)
static FFT::Complex operator+ (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r + b.r, a.i + b.i }; return c; }
static FFT::Complex operator- (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r - b.r, a.i - b.i }; return c; }
static FFT::Complex operator* (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r }; return c; }
static FFT::Complex& operator+= (FFT::Complex& a, FFT::Complex b) noexcept { a.r += b.r; a.i += b.i; return a; }
//==============================================================================
struct FFT::FFTConfig
{
FFTConfig (int sizeOfFFT, bool isInverse)
: fftSize (sizeOfFFT), inverse (isInverse), twiddleTable ((size_t) sizeOfFFT)
{
for (int i = 0; i < fftSize; ++i)
{
const double phase = (isInverse ? 2.0 : -2.0) * double_Pi * i / fftSize;
twiddleTable[i].r = (float) cos (phase);
twiddleTable[i].i = (float) sin (phase);
}
const int root = (int) std::sqrt ((double) fftSize);
int divisor = 4, n = fftSize;
for (int i = 0; i < numElementsInArray (factors); ++i)
{
while ((n % divisor) != 0)
{
if (divisor == 2) divisor = 3;
else if (divisor == 4) divisor = 2;
else divisor += 2;
if (divisor > root)
divisor = n;
}
n /= divisor;
jassert (divisor == 1 || divisor == 2 || divisor == 4);
factors[i].radix = divisor;
factors[i].length = n;
}
}
void perform (const Complex* input, Complex* output) const noexcept
{
perform (input, output, 1, 1, factors);
}
const int fftSize;
const bool inverse;
struct Factor { int radix, length; };
Factor factors[32];
HeapBlock<Complex> twiddleTable;
void perform (const Complex* input, Complex* output, const int stride, const int strideIn, const Factor* facs) const noexcept
{
const Factor factor (*facs++);
Complex* const originalOutput = output;
const Complex* const outputEnd = output + factor.radix * factor.length;
if (stride == 1 && factor.radix <= 5)
{
for (int i = 0; i < factor.radix; ++i)
perform (input + stride * strideIn * i, output + i * factor.length, stride * factor.radix, strideIn, facs);
butterfly (factor, output, stride);
return;
}
if (factor.length == 1)
{
do
{
*output++ = *input;
input += stride * strideIn;
}
while (output < outputEnd);
}
else
{
do
{
perform (input, output, stride * factor.radix, strideIn, facs);
input += stride * strideIn;
output += factor.length;
}
while (output < outputEnd);
}
butterfly (factor, originalOutput, stride);
}
void butterfly (const Factor factor, Complex* data, const int stride) const noexcept
{
switch (factor.radix)
{
case 1: break;
case 2: butterfly2 (data, stride, factor.length); return;
case 4: butterfly4 (data, stride, factor.length); return;
default: jassertfalse; break;
}
Complex* scratch = static_cast<Complex*> (alloca (sizeof (Complex) * (size_t) factor.radix));
for (int i = 0; i < factor.length; ++i)
{
for (int k = i, q1 = 0; q1 < factor.radix; ++q1)
{
scratch[q1] = data[k];
k += factor.length;
}
for (int k = i, q1 = 0; q1 < factor.radix; ++q1)
{
int twiddleIndex = 0;
data[k] = scratch[0];
for (int q = 1; q < factor.radix; ++q)
{
twiddleIndex += stride * k;
if (twiddleIndex >= fftSize)
twiddleIndex -= fftSize;
data[k] += scratch[q] * twiddleTable[twiddleIndex];
}
k += factor.length;
}
}
}
void butterfly2 (Complex* data, const int stride, const int length) const noexcept
{
Complex* dataEnd = data + length;
const Complex* tw = twiddleTable;
for (int i = length; --i >= 0;)
{
const Complex s (*dataEnd * *tw);
tw += stride;
*dataEnd++ = *data - s;
*data++ += s;
}
}
void butterfly4 (Complex* data, const int stride, const int length) const noexcept
{
const int lengthX2 = length * 2;
const int lengthX3 = length * 3;
const Complex* twiddle1 = twiddleTable;
const Complex* twiddle2 = twiddle1;
const Complex* twiddle3 = twiddle1;
for (int i = length; --i >= 0;)
{
const Complex s0 = data[length] * *twiddle1;
const Complex s1 = data[lengthX2] * *twiddle2;
const Complex s2 = data[lengthX3] * *twiddle3;
const Complex s3 = s0 + s2;
const Complex s4 = s0 - s2;
const Complex s5 = *data - s1;
*data += s1;
data[lengthX2] = *data - s3;
twiddle1 += stride;
twiddle2 += stride * 2;
twiddle3 += stride * 3;
*data += s3;
if (inverse)
{
data[length].r = s5.r - s4.i;
data[length].i = s5.i + s4.r;
data[lengthX3].r = s5.r + s4.i;
data[lengthX3].i = s5.i - s4.r;
}
else
{
data[length].r = s5.r + s4.i;
data[length].i = s5.i - s4.r;
data[lengthX3].r = s5.r - s4.i;
data[lengthX3].i = s5.i + s4.r;
}
++data;
}
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFTConfig)
};
//==============================================================================
FFT::FFT (int order, bool inverse) : config (new FFTConfig (1 << order, inverse)), size (1 << order) {}
FFT::~FFT() {}
void FFT::perform (const Complex* const input, Complex* const output) const noexcept
{
config->perform (input, output);
}
void FFT::performRealOnlyForwardTransform (float* d) const noexcept
{
// This can only be called on an FFT object that was created to do forward transforms.
jassert (! config->inverse);
Complex* const scratch = static_cast<Complex*> (alloca (16 + sizeof (Complex) * (size_t) size));
for (int i = 0; i < size; ++i)
{
scratch[i].r = d[i];
scratch[i].i = 0;
}
perform (scratch, reinterpret_cast<Complex*> (d));
}
void FFT::performRealOnlyInverseTransform (float* d) const noexcept
{
// This can only be called on an FFT object that was created to do inverse transforms.
jassert (config->inverse);
Complex* const scratch = static_cast<Complex*> (alloca (16 + sizeof (Complex) * (size_t) size));
perform (reinterpret_cast<const Complex*> (d), scratch);
const float scaleFactor = 1.0f / size;
for (int i = 0; i < size; ++i)
{
d[i] = scratch[i].r * scaleFactor;
d[i + size] = scratch[i].i * scaleFactor;
}
}
void FFT::performFrequencyOnlyForwardTransform (float* d) const noexcept
{
performRealOnlyForwardTransform (d);
const int twiceSize = size * 2;
for (int i = 0; i < twiceSize; i += 2)
{
d[i / 2] = juce_hypot (d[i], d[i + 1]);
if (i >= size)
{
d[i] = 0;
d[i + 1] = 0;
}
}
}

+ 92
- 0
libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.h View File

@@ -0,0 +1,92 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/**
A very minimal FFT class.
This is only a simple low-footprint implementation and isn't tuned for speed - it may
be useful for simple applications where one of the more complex FFT libraries would be
overkill. (But in the future it may end up becoming optimised of course...)
The FFT class itself contains lookup tables, so there's some overhead in creating
one, you should create and cache an FFT object for each size/direction of transform
that you need, and re-use them to perform the actual operation.
*/
class JUCE_API FFT
{
public:
/** Initialises an object for performing either a forward or inverse FFT with the given size.
The the number of points the FFT will operate on will be 2 ^ order.
*/
FFT (int order, bool isInverse);
/** Destructor. */
~FFT();
/** A complex number, for the purposes of the FFT class. */
struct Complex
{
float r; /**< Real part. */
float i; /**< Imaginary part. */
};
/** Performs an out-of-place FFT, either forward or inverse depending on the mode
that was passed to this object's constructor.
The arrays must contain at least getSize() elements.
*/
void perform (const Complex* input, Complex* output) const noexcept;
/** Performs an in-place forward transform on a block of real data.
The size of the array passed in must be 2 * getSize(), and the first half
should contain your raw input sample data. On return, the array will contain
complex frequency + phase data, and can be passed to performRealOnlyInverseTransform()
in order to convert it back to reals.
*/
void performRealOnlyForwardTransform (float* inputOutputData) const noexcept;
/** Performs a reverse operation to data created in performRealOnlyForwardTransform().
The size of the array passed in must be 2 * getSize(), containing complex
frequency and phase data. On return, the first half of the array will contain
the reconstituted samples.
*/
void performRealOnlyInverseTransform (float* inputOutputData) const noexcept;
/** Takes an array and simply transforms it to the frequency spectrum.
This may be handy for things like frequency displays or analysis.
*/
void performFrequencyOnlyForwardTransform (float* inputOutputData) const noexcept;
/** Returns the number of data points that this FFT was created to work with. */
int getSize() const noexcept { return size; }
private:
struct FFTConfig;
ScopedPointer<FFTConfig> config;
const int size;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFT)
};

+ 3
- 3
libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp View File

@@ -23,7 +23,7 @@
*/
#if JUCE_INTEL
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0;
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0;
#else
#define JUCE_SNAP_TO_ZERO(n)
#endif
@@ -64,7 +64,7 @@ IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate,
{
jassert (sampleRate > 0);
const double n = 1.0 / tan (double_Pi * frequency / sampleRate);
const double n = 1.0 / std::tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
@@ -79,7 +79,7 @@ IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate,
IIRCoefficients IIRCoefficients::makeHighPass (const double sampleRate,
const double frequency) noexcept
{
const double n = tan (double_Pi * frequency / sampleRate);
const double n = std::tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);


+ 0
- 239
libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp View File

@@ -1,239 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#if JUCE_INTEL
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0;
#else
#define JUCE_SNAP_TO_ZERO(n)
#endif
//==============================================================================
IIRFilterOld::IIRFilterOld()
: active (false), v1 (0), v2 (0)
{
zeromem (coefficients, sizeof (coefficients));
}
IIRFilterOld::IIRFilterOld (const IIRFilterOld& other)
: active (other.active), v1 (0), v2 (0)
{
const SpinLock::ScopedLockType sl (other.processLock);
memcpy (coefficients, other.coefficients, sizeof (coefficients));
}
IIRFilterOld::~IIRFilterOld()
{
}
//==============================================================================
void IIRFilterOld::reset() noexcept
{
const SpinLock::ScopedLockType sl (processLock);
v1 = v2 = 0;
}
float IIRFilterOld::processSingleSampleRaw (const float in) noexcept
{
float out = coefficients[0] * in + v1;
JUCE_SNAP_TO_ZERO (out);
v1 = coefficients[1] * in - coefficients[3] * out + v2;
v2 = coefficients[2] * in - coefficients[4] * out;
return out;
}
void IIRFilterOld::processSamples (float* const samples,
const int numSamples) noexcept
{
const SpinLock::ScopedLockType sl (processLock);
if (active)
{
const float c0 = coefficients[0];
const float c1 = coefficients[1];
const float c2 = coefficients[2];
const float c3 = coefficients[3];
const float c4 = coefficients[4];
float lv1 = v1, lv2 = v2;
for (int i = 0; i < numSamples; ++i)
{
const float in = samples[i];
const float out = c0 * in + lv1;
samples[i] = out;
lv1 = c1 * in - c3 * out + lv2;
lv2 = c2 * in - c4 * out;
}
JUCE_SNAP_TO_ZERO (lv1); v1 = lv1;
JUCE_SNAP_TO_ZERO (lv2); v2 = lv2;
}
}
//==============================================================================
void IIRFilterOld::makeLowPass (const double sampleRate,
const double frequency) noexcept
{
jassert (sampleRate > 0);
const double n = 1.0 / tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
setCoefficients (c1,
c1 * 2.0f,
c1,
1.0,
c1 * 2.0 * (1.0 - nSquared),
c1 * (1.0 - std::sqrt (2.0) * n + nSquared));
}
void IIRFilterOld::makeHighPass (const double sampleRate,
const double frequency) noexcept
{
const double n = tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
setCoefficients (c1,
c1 * -2.0f,
c1,
1.0,
c1 * 2.0 * (nSquared - 1.0),
c1 * (1.0 - std::sqrt (2.0) * n + nSquared));
}
void IIRFilterOld::makeLowShelf (const double sampleRate,
const double cutOffFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double aminus1 = A - 1.0;
const double aplus1 = A + 1.0;
const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
const double coso = std::cos (omega);
const double beta = std::sin (omega) * std::sqrt (A) / Q;
const double aminus1TimesCoso = aminus1 * coso;
setCoefficients (A * (aplus1 - aminus1TimesCoso + beta),
A * 2.0 * (aminus1 - aplus1 * coso),
A * (aplus1 - aminus1TimesCoso - beta),
aplus1 + aminus1TimesCoso + beta,
-2.0 * (aminus1 + aplus1 * coso),
aplus1 + aminus1TimesCoso - beta);
}
void IIRFilterOld::makeHighShelf (const double sampleRate,
const double cutOffFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double aminus1 = A - 1.0;
const double aplus1 = A + 1.0;
const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
const double coso = std::cos (omega);
const double beta = std::sin (omega) * std::sqrt (A) / Q;
const double aminus1TimesCoso = aminus1 * coso;
setCoefficients (A * (aplus1 + aminus1TimesCoso + beta),
A * -2.0 * (aminus1 + aplus1 * coso),
A * (aplus1 + aminus1TimesCoso - beta),
aplus1 - aminus1TimesCoso + beta,
2.0 * (aminus1 - aplus1 * coso),
aplus1 - aminus1TimesCoso - beta);
}
void IIRFilterOld::makeBandPass (const double sampleRate,
const double centreFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double omega = (double_Pi * 2.0 * jmax (centreFrequency, 2.0)) / sampleRate;
const double alpha = 0.5 * std::sin (omega) / Q;
const double c2 = -2.0 * std::cos (omega);
const double alphaTimesA = alpha * A;
const double alphaOverA = alpha / A;
setCoefficients (1.0 + alphaTimesA,
c2,
1.0 - alphaTimesA,
1.0 + alphaOverA,
c2,
1.0 - alphaOverA);
}
void IIRFilterOld::makeInactive() noexcept
{
const SpinLock::ScopedLockType sl (processLock);
active = false;
}
//==============================================================================
void IIRFilterOld::copyCoefficientsFrom (const IIRFilterOld& other) noexcept
{
const SpinLock::ScopedLockType sl (processLock);
memcpy (coefficients, other.coefficients, sizeof (coefficients));
active = other.active;
}
//==============================================================================
void IIRFilterOld::setCoefficients (double c1, double c2, double c3,
double c4, double c5, double c6) noexcept
{
const double a = 1.0 / c4;
c1 *= a;
c2 *= a;
c3 *= a;
c5 *= a;
c6 *= a;
const SpinLock::ScopedLockType sl (processLock);
coefficients[0] = (float) c1;
coefficients[1] = (float) c2;
coefficients[2] = (float) c3;
coefficients[3] = (float) c5;
coefficients[4] = (float) c6;
active = true;
}
#undef JUCE_SNAP_TO_ZERO

+ 0
- 148
libs/juce/source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h View File

@@ -1,148 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef __JUCE_IIRFILTER_OLD_JUCEHEADER__
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__
//==============================================================================
/**
An IIR filter that can perform low, high, or band-pass filtering on an
audio signal.
@see IIRFilterAudioSource
*/
class JUCE_API IIRFilterOld
{
public:
//==============================================================================
/** Creates a filter.
Initially the filter is inactive, so will have no effect on samples that
you process with it. Use the appropriate method to turn it into the type
of filter needed.
*/
IIRFilterOld();
/** Creates a copy of another filter. */
IIRFilterOld (const IIRFilterOld& other);
/** Destructor. */
~IIRFilterOld();
//==============================================================================
/** Resets the filter's processing pipeline, ready to start a new stream of data.
Note that this clears the processing state, but the type of filter and
its coefficients aren't changed. To put a filter into an inactive state, use
the makeInactive() method.
*/
void reset() noexcept;
/** Performs the filter operation on the given set of samples.
*/
void processSamples (float* samples,
int numSamples) noexcept;
/** Processes a single sample, without any locking or checking.
Use this if you need fast processing of a single value, but be aware that
this isn't thread-safe in the way that processSamples() is.
*/
float processSingleSampleRaw (float sample) noexcept;
//==============================================================================
/** Sets the filter up to act as a low-pass filter.
*/
void makeLowPass (double sampleRate,
double frequency) noexcept;
/** Sets the filter up to act as a high-pass filter.
*/
void makeHighPass (double sampleRate,
double frequency) noexcept;
//==============================================================================
/** Sets the filter up to act as a low-pass shelf filter with variable Q and gain.
The gain is a scale factor that the low frequencies are multiplied by, so values
greater than 1.0 will boost the low frequencies, values less than 1.0 will
attenuate them.
*/
void makeLowShelf (double sampleRate,
double cutOffFrequency,
double Q,
float gainFactor) noexcept;
/** Sets the filter up to act as a high-pass shelf filter with variable Q and gain.
The gain is a scale factor that the high frequencies are multiplied by, so values
greater than 1.0 will boost the high frequencies, values less than 1.0 will
attenuate them.
*/
void makeHighShelf (double sampleRate,
double cutOffFrequency,
double Q,
float gainFactor) noexcept;
/** Sets the filter up to act as a band pass filter centred around a
frequency, with a variable Q and gain.
The gain is a scale factor that the centre frequencies are multiplied by, so
values greater than 1.0 will boost the centre frequencies, values less than
1.0 will attenuate them.
*/
void makeBandPass (double sampleRate,
double centreFrequency,
double Q,
float gainFactor) noexcept;
/** Clears the filter's coefficients so that it becomes inactive.
*/
void makeInactive() noexcept;
//==============================================================================
/** Makes this filter duplicate the set-up of another one.
*/
void copyCoefficientsFrom (const IIRFilterOld& other) noexcept;
protected:
//==============================================================================
SpinLock processLock;
void setCoefficients (double c1, double c2, double c3,
double c4, double c5, double c6) noexcept;
bool active;
float coefficients[5];
float v1, v2;
// (use the copyCoefficientsFrom() method instead of this operator)
IIRFilterOld& operator= (const IIRFilterOld&);
JUCE_LEAK_DETECTOR (IIRFilterOld)
};
#endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__

+ 8
- 2
libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp View File

@@ -87,7 +87,10 @@ int LagrangeInterpolator::process (const double actualRatio, const float* in,
if (numOut >= 4)
{
memcpy (lastInputSamples, in + (numOut - 4), 4 * sizeof (float));
const float* end = in + numOut;
for (int i = 0; i < 4; ++i)
lastInputSamples[i] = *--end;
}
else
{
@@ -152,7 +155,10 @@ int LagrangeInterpolator::processAdding (const double actualRatio, const float*
if (numOut >= 4)
{
memcpy (lastInputSamples, in + (numOut - 4), 4 * sizeof (float));
const float* end = in + numOut;
for (int i = 0; i < 4; ++i)
lastInputSamples[i] = *--end;
}
else
{


+ 92
- 43
libs/juce/source/modules/juce_audio_basics/effects/juce_Reverb.h View File

@@ -82,12 +82,13 @@ public:
const float dryScaleFactor = 2.0f;
const float wet = newParams.wetLevel * wetScaleFactor;
wet1 = wet * (newParams.width * 0.5f + 0.5f);
wet2 = wet * (1.0f - newParams.width) * 0.5f;
dry = newParams.dryLevel * dryScaleFactor;
dryGain.setValue (newParams.dryLevel * dryScaleFactor);
wetGain1.setValue (0.5f * wet * (1.0f + newParams.width));
wetGain2.setValue (0.5f * wet * (1.0f - newParams.width));
gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f;
parameters = newParams;
shouldUpdateDamping = true;
updateDamping();
}
//==============================================================================
@@ -115,7 +116,12 @@ public:
allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100);
}
shouldUpdateDamping = true;
const double smoothTime = 0.01;
damping .reset (sampleRate, smoothTime);
feedback.reset (sampleRate, smoothTime);
dryGain .reset (sampleRate, smoothTime);
wetGain1.reset (sampleRate, smoothTime);
wetGain2.reset (sampleRate, smoothTime);
}
/** Clears the reverb's buffers. */
@@ -137,18 +143,18 @@ public:
{
jassert (left != nullptr && right != nullptr);
if (shouldUpdateDamping)
updateDamping();
for (int i = 0; i < numSamples; ++i)
{
const float input = (left[i] + right[i]) * gain;
float outL = 0, outR = 0;
const float damp = damping.getNextValue();
const float feedbck = feedback.getNextValue();
for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel
{
outL += comb[0][j].process (input);
outR += comb[1][j].process (input);
outL += comb[0][j].process (input, damp, feedbck);
outR += comb[1][j].process (input, damp, feedbck);
}
for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
@@ -157,6 +163,10 @@ public:
outR = allPass[1][j].process (outR);
}
const float dry = dryGain.getNextValue();
const float wet1 = wetGain1.getNextValue();
const float wet2 = wetGain2.getNextValue();
left[i] = outL * wet1 + outR * wet2 + left[i] * dry;
right[i] = outR * wet1 + outL * wet2 + right[i] * dry;
}
@@ -167,32 +177,30 @@ public:
{
jassert (samples != nullptr);
if (shouldUpdateDamping)
updateDamping();
for (int i = 0; i < numSamples; ++i)
{
const float input = samples[i] * gain;
float output = 0;
const float damp = damping.getNextValue();
const float feedbck = feedback.getNextValue();
for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel
output += comb[0][j].process (input);
output += comb[0][j].process (input, damp, feedbck);
for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
output = allPass[0][j].process (output);
const float dry = dryGain.getNextValue();
const float wet1 = wetGain1.getNextValue();
samples[i] = output * wet1 + samples[i] * dry;
}
}
private:
//==============================================================================
Parameters parameters;
volatile bool shouldUpdateDamping;
float gain, wet1, wet2, dry;
inline static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; }
static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; }
void updateDamping() noexcept
{
@@ -200,8 +208,6 @@ private:
const float roomOffset = 0.7f;
const float dampScaleFactor = 0.4f;
shouldUpdateDamping = false;
if (isFrozen (parameters.freezeMode))
setDamping (0.0f, 1.0f);
else
@@ -211,19 +217,15 @@ private:
void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept
{
for (int j = 0; j < numChannels; ++j)
for (int i = numCombs; --i >= 0;)
comb[j][i].setFeedbackAndDamp (roomSizeToUse, dampingToUse);
damping.setValue (dampingToUse);
feedback.setValue (roomSizeToUse);
}
//==============================================================================
class CombFilter
{
public:
CombFilter() noexcept
: bufferSize (0), bufferIndex (0),
feedback (0), last (0), damp1 (0), damp2 (0)
{}
CombFilter() noexcept : bufferSize (0), bufferIndex (0), last (0) {}
void setSize (const int size)
{
@@ -243,22 +245,15 @@ private:
buffer.clear ((size_t) bufferSize);
}
void setFeedbackAndDamp (const float f, const float d) noexcept
{
damp1 = d;
damp2 = 1.0f - d;
feedback = f;
}
inline float process (const float input) noexcept
float process (const float input, const float damp, const float feedbackLevel) noexcept
{
const float output = buffer [bufferIndex];
last = (output * damp2) + (last * damp1);
const float output = buffer[bufferIndex];
last = (output * (1.0f - damp)) + (last * damp);
JUCE_UNDENORMALISE (last);
float temp = input + (last * feedback);
float temp = input + (last * feedbackLevel);
JUCE_UNDENORMALISE (temp);
buffer [bufferIndex] = temp;
buffer[bufferIndex] = temp;
bufferIndex = (bufferIndex + 1) % bufferSize;
return output;
}
@@ -266,7 +261,7 @@ private:
private:
HeapBlock<float> buffer;
int bufferSize, bufferIndex;
float feedback, last, damp1, damp2;
float last;
JUCE_DECLARE_NON_COPYABLE (CombFilter)
};
@@ -294,7 +289,7 @@ private:
buffer.clear ((size_t) bufferSize);
}
inline float process (const float input) noexcept
float process (const float input) noexcept
{
const float bufferedValue = buffer [bufferIndex];
float temp = input + (bufferedValue * 0.5f);
@@ -311,11 +306,65 @@ private:
JUCE_DECLARE_NON_COPYABLE (AllPassFilter)
};
//==============================================================================
class LinearSmoothedValue
{
public:
LinearSmoothedValue() noexcept
: currentValue (0), target (0), step (0), countdown (0), stepsToTarget (0)
{
}
void reset (double sampleRate, double fadeLengthSeconds) noexcept
{
jassert (sampleRate > 0 && fadeLengthSeconds >= 0);
stepsToTarget = (int) std::floor (fadeLengthSeconds * sampleRate);
currentValue = target;
countdown = 0;
}
void setValue (float newValue) noexcept
{
if (target != newValue)
{
target = newValue;
countdown = stepsToTarget;
if (countdown <= 0)
currentValue = target;
else
step = (target - currentValue) / countdown;
}
}
float getNextValue() noexcept
{
if (countdown <= 0)
return target;
--countdown;
currentValue += step;
return currentValue;
}
private:
float currentValue, target, step;
int countdown, stepsToTarget;
JUCE_DECLARE_NON_COPYABLE (LinearSmoothedValue)
};
//==============================================================================
enum { numCombs = 8, numAllPasses = 4, numChannels = 2 };
Parameters parameters;
float gain;
CombFilter comb [numChannels][numCombs];
AllPassFilter allPass [numChannels][numAllPasses];
LinearSmoothedValue damping, feedback, dryGain, wetGain1, wetGain2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb)
};


+ 1
- 1
libs/juce/source/modules/juce_audio_basics/juce_audio_basics.cpp View File

@@ -76,8 +76,8 @@ namespace juce
#include "buffers/juce_AudioSampleBuffer.cpp"
#include "buffers/juce_FloatVectorOperations.cpp"
#include "effects/juce_IIRFilter.cpp"
#include "effects/juce_IIRFilterOld.cpp"
#include "effects/juce_LagrangeInterpolator.cpp"
#include "effects/juce_FFT.cpp"
#include "midi/juce_MidiBuffer.cpp"
#include "midi/juce_MidiFile.cpp"
#include "midi/juce_MidiKeyboardState.cpp"


+ 4
- 1
libs/juce/source/modules/juce_audio_basics/juce_audio_basics.h View File

@@ -31,13 +31,16 @@
namespace juce
{
#undef Complex // apparently some C libraries actually define these symbols (!)
#undef Factor
#include "buffers/juce_AudioDataConverters.h"
#include "buffers/juce_AudioSampleBuffer.h"
#include "buffers/juce_FloatVectorOperations.h"
#include "effects/juce_Decibels.h"
#include "effects/juce_IIRFilter.h"
#include "effects/juce_IIRFilterOld.h"
#include "effects/juce_LagrangeInterpolator.h"
#include "effects/juce_FFT.h"
#include "effects/juce_Reverb.h"
#include "midi/juce_MidiMessage.h"
#include "midi/juce_MidiBuffer.h"


+ 1
- 1
libs/juce/source/modules/juce_audio_basics/juce_module_info View File

@@ -1,7 +1,7 @@
{
"id": "juce_audio_basics",
"name": "JUCE audio and midi data classes",
"version": "3.0.8",
"version": "3.1.1",
"description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc",
"website": "http://www.juce.com/juce",
"license": "GPL/Commercial",


+ 15
- 21
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp View File

@@ -276,14 +276,11 @@ void MidiMessageSequence::deleteSysExMessages()
}
//==============================================================================
void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber,
const double time,
OwnedArray<MidiMessage>& dest)
void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber, const double time, Array<MidiMessage>& dest)
{
bool doneProg = false;
bool donePitchWheel = false;
Array<int> doneControllers;
doneControllers.ensureStorageAllocated (32);
bool doneControllers[128] = { 0 };
for (int i = list.size(); --i >= 0;)
{
@@ -291,28 +288,25 @@ void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumbe
if (mm.isForChannel (channelNumber) && mm.getTimeStamp() <= time)
{
if (mm.isProgramChange())
if (mm.isProgramChange() && ! doneProg)
{
if (! doneProg)
{
dest.add (new MidiMessage (mm, 0.0));
doneProg = true;
}
doneProg = true;
dest.add (MidiMessage (mm, 0.0));
}
else if (mm.isController())
else if (mm.isPitchWheel() && ! donePitchWheel)
{
if (! doneControllers.contains (mm.getControllerNumber()))
{
dest.add (new MidiMessage (mm, 0.0));
doneControllers.add (mm.getControllerNumber());
}
donePitchWheel = true;
dest.add (MidiMessage (mm, 0.0));
}
else if (mm.isPitchWheel())
else if (mm.isController())
{
if (! donePitchWheel)
const int controllerNumber = mm.getControllerNumber();
jassert (isPositiveAndBelow (controllerNumber, 128));
if (! doneControllers[controllerNumber])
{
dest.add (new MidiMessage (mm, 0.0));
donePitchWheel = true;
doneControllers[controllerNumber] = true;
dest.add (MidiMessage (mm, 0.0));
}
}
}


+ 1
- 1
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h View File

@@ -247,7 +247,7 @@ public:
state at the required time.
*/
void createControllerUpdatesForTime (int channelNumber, double time,
OwnedArray<MidiMessage>& resultMessages);
Array<MidiMessage>& resultMessages);
//==============================================================================
/** Swaps this sequence with another one. */


+ 9
- 7
libs/juce/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp View File

@@ -24,14 +24,14 @@
ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource,
const bool deleteInputWhenDeleted,
const int numChannels_)
const int channels)
: input (inputSource, deleteInputWhenDeleted),
ratio (1.0),
lastRatio (1.0),
bufferPos (0),
sampsInBuffer (0),
subSampleOffset (0),
numChannels (numChannels_)
numChannels (channels)
{
jassert (input != nullptr);
zeromem (coefficients, sizeof (coefficients));
@@ -51,9 +51,10 @@ void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected, double s
{
const SpinLock::ScopedLockType sl (ratioLock);
input->prepareToPlay (samplesPerBlockExpected, sampleRate);
const int scaledBlockSize = roundToInt (samplesPerBlockExpected * ratio);
input->prepareToPlay (scaledBlockSize, sampleRate * ratio);
buffer.setSize (numChannels, roundToInt (samplesPerBlockExpected * ratio) + 32);
buffer.setSize (numChannels, scaledBlockSize + 32);
filterStates.calloc ((size_t) numChannels);
srcBuffers.calloc ((size_t) numChannels);
@@ -93,7 +94,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
lastRatio = localRatio;
}
const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 2;
const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 3;
int bufferSize = buffer.getNumSamples();
@@ -138,8 +139,11 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
}
int nextPos = (bufferPos + 1) % bufferSize;
for (int m = info.numSamples; --m >= 0;)
{
jassert (sampsInBuffer > 0 && nextPos != endOfBufferPos);
const float alpha = (float) subSampleOffset;
for (int channel = 0; channel < channelsToProcess; ++channel)
@@ -148,8 +152,6 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
subSampleOffset += localRatio;
jassert (sampsInBuffer > 0);
while (subSampleOffset >= 1.0)
{
if (++bufferPos >= bufferSize)


+ 21
- 13
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -29,6 +29,7 @@ SynthesiserSound::~SynthesiserSound() {}
SynthesiserVoice::SynthesiserVoice()
: currentSampleRate (44100.0),
currentlyPlayingNote (-1),
currentPlayingMidiChannel (0),
noteOnTime (0),
keyIsDown (false),
sostenutoPedalDown (false)
@@ -41,8 +42,7 @@ SynthesiserVoice::~SynthesiserVoice()
bool SynthesiserVoice::isPlayingChannel (const int midiChannel) const
{
return currentlyPlayingSound != nullptr
&& currentlyPlayingSound->appliesToChannel (midiChannel);
return currentPlayingMidiChannel == midiChannel;
}
void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate)
@@ -50,10 +50,16 @@ void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate)
currentSampleRate = newRate;
}
bool SynthesiserVoice::isVoiceActive() const
{
return getCurrentlyPlayingNote() >= 0;
}
void SynthesiserVoice::clearCurrentNote()
{
currentlyPlayingNote = -1;
currentlyPlayingSound = nullptr;
currentPlayingMidiChannel = 0;
}
void SynthesiserVoice::aftertouchChanged (int) {}
@@ -253,14 +259,15 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
if (voice->currentlyPlayingSound != nullptr)
voice->stopNote (0.0f, false);
voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]);
voice->currentlyPlayingNote = midiNoteNumber;
voice->currentPlayingMidiChannel = midiChannel;
voice->noteOnTime = ++lastNoteOnCounter;
voice->currentlyPlayingSound = sound;
voice->keyIsDown = true;
voice->sostenutoPedalDown = false;
voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]);
}
}
@@ -285,7 +292,8 @@ void Synthesiser::noteOff (const int midiChannel,
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->getCurrentlyPlayingNote() == midiNoteNumber)
if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& voice->isPlayingChannel (midiChannel))
{
if (SynthesiserSound* const sound = voice->getCurrentlyPlayingSound())
{
@@ -426,7 +434,7 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->getCurrentlyPlayingNote() < 0 && voice->canPlaySound (soundToPlay))
if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay))
return voice;
}
@@ -440,7 +448,7 @@ struct VoiceAgeSorter
{
static int compareElements (SynthesiserVoice* v1, SynthesiserVoice* v2) noexcept
{
return v1->wasStartedBefore (*v2) ? 1 : (v2->wasStartedBefore (*v1) ? -1 : 0);
return v1->wasStartedBefore (*v2) ? -1 : (v2->wasStartedBefore (*v1) ? 1 : 0);
}
};
@@ -473,10 +481,10 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
}
}
jassert (bottom != nullptr && top != nullptr);
const int stealableVoiceRange = usableVoices.size() - 6;
// The oldest note that's playing with the target pitch playing is ideal..
for (int i = 0; i < usableVoices.size(); ++i)
for (int i = 0; i < stealableVoiceRange; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
@@ -485,7 +493,7 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
}
// ..otherwise, look for the oldest note that isn't the top or bottom note..
for (int i = 0; i < usableVoices.size(); ++i)
for (int i = 0; i < stealableVoiceRange; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
@@ -493,6 +501,6 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
return voice;
}
// ..otherwise, there's only one or two voices to choose from - we'll return the top one..
return top;
// ..otherwise, there's only one or two voices to choose from - we'll return the oldest one..
return usableVoices.getFirst();
}

+ 13
- 7
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -140,6 +140,12 @@ public:
*/
virtual void stopNote (float velocity, bool allowTailOff) = 0;
/** Returns true if this voice is currently busy playing a sound.
By default this just checks the getCurrentlyPlayingNote() value, but can
be overridden for more advanced checking.
*/
virtual bool isVoiceActive() const;
/** Called to let the voice know that the pitch wheel has been moved.
This will be called during the rendering callback, so must be fast and thread-safe.
*/
@@ -185,17 +191,17 @@ public:
*/
virtual void setCurrentPlaybackSampleRate (double newRate);
/** Returns the current target sample rate at which rendering is being done.
Subclasses may need to know this so that they can pitch things correctly.
*/
double getSampleRate() const noexcept { return currentSampleRate; }
/** Returns true if the voice is currently playing a sound which is mapped to the given
midi channel.
If it's not currently playing, this will return false.
*/
bool isPlayingChannel (int midiChannel) const;
virtual bool isPlayingChannel (int midiChannel) const;
/** Returns the current target sample rate at which rendering is being done.
Subclasses may need to know this so that they can pitch things correctly.
*/
double getSampleRate() const noexcept { return currentSampleRate; }
/** Returns true if the key that triggered this voice is still held down.
Note that the voice may still be playing after the key was released (e.g because the
@@ -230,7 +236,7 @@ private:
friend class Synthesiser;
double currentSampleRate;
int currentlyPlayingNote;
int currentlyPlayingNote, currentPlayingMidiChannel;
uint32 noteOnTime;
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sostenutoPedalDown;


+ 18
- 13
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -92,7 +92,6 @@ AudioDeviceManager::AudioDeviceManager()
: numInputChansNeeded (0),
numOutputChansNeeded (2),
listNeedsScanning (true),
useInputNames (false),
inputLevel (0),
testSoundPosition (0),
cpuUsageMs (0),
@@ -154,13 +153,14 @@ static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType
void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>& list)
{
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (false));
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (true));
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());
addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());
}
@@ -177,6 +177,17 @@ void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType)
}
}
static bool deviceListContains (AudioIODeviceType* type, bool isInput, const String& name)
{
StringArray devices (type->getDeviceNames (isInput));
for (int i = devices.size(); --i >= 0;)
if (devices[i].trim().equalsIgnoreCase (name.trim()))
return true;
return false;
}
//==============================================================================
String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
const int numOutputChannelsNeeded,
@@ -363,8 +374,8 @@ AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const
{
AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i);
if ((inputName.isNotEmpty() && type->getDeviceNames (true).contains (inputName, true))
|| (outputName.isNotEmpty() && type->getDeviceNames (false).contains (outputName, true)))
if ((inputName.isNotEmpty() && deviceListContains (type, true, inputName))
|| (outputName.isNotEmpty() && deviceListContains (type, false, outputName)))
{
return type;
}
@@ -458,17 +469,11 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup
deleteCurrentDevice();
scanDevicesIfNeeded();
if (newOutputDeviceName.isNotEmpty()
&& ! type->getDeviceNames (false).contains (newOutputDeviceName))
{
if (newOutputDeviceName.isNotEmpty() && ! deviceListContains (type, false, newOutputDeviceName))
return "No such device: " + newOutputDeviceName;
}
if (newInputDeviceName.isNotEmpty()
&& ! type->getDeviceNames (true).contains (newInputDeviceName))
{
if (newInputDeviceName.isNotEmpty() && ! deviceListContains (type, true, newInputDeviceName))
return "No such device: " + newInputDeviceName;
}
currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName);


+ 0
- 1
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h View File

@@ -450,7 +450,6 @@ private:
BigInteger inputChannels, outputChannels;
ScopedPointer<XmlElement> lastExplicitSettings;
mutable bool listNeedsScanning;
bool useInputNames;
Atomic<int> inputLevelMeasurementEnabledCount;
double inputLevel;
ScopedPointer<AudioSampleBuffer> testSound;


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp View File

@@ -50,7 +50,7 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio()
#endif
#if ! (JUCE_WINDOWS && JUCE_WASAPI)
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { return nullptr; }
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool) { return nullptr; }
#endif
#if ! (JUCE_WINDOWS && JUCE_DIRECTSOUND)


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h View File

@@ -151,7 +151,7 @@ public:
/** Creates an iOS device type if it's available on this platform, or returns null. */
static AudioIODeviceType* createAudioIODeviceType_iOSAudio();
/** Creates a WASAPI device type if it's available on this platform, or returns null. */
static AudioIODeviceType* createAudioIODeviceType_WASAPI();
static AudioIODeviceType* createAudioIODeviceType_WASAPI (bool exclusiveMode);
/** Creates a DirectSound device type if it's available on this platform, or returns null. */
static AudioIODeviceType* createAudioIODeviceType_DirectSound();
/** Creates an ASIO device type if it's available on this platform, or returns null. */


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/juce_audio_devices.cpp View File

@@ -72,7 +72,7 @@
This means that anyone who wants to use JUCE's ASIO abilities will have to:
1) Agree to Steinberg's licensing terms and download the ASIO SDK
(see www.steinberg.net/Steinberg/Developers.asp).
(see http://www.steinberg.net/en/company/developers.html).
2) Enable this code with a global definition #define JUCE_ASIO 1.


+ 10
- 1
libs/juce/source/modules/juce_audio_devices/juce_audio_devices.h View File

@@ -43,12 +43,21 @@
#endif
/** Config: JUCE_WASAPI
Enables WASAPI audio devices (Windows Vista and above).
Enables WASAPI audio devices (Windows Vista and above). See also the
JUCE_WASAPI_EXCLUSIVE flag.
*/
#ifndef JUCE_WASAPI
#define JUCE_WASAPI 1
#endif
/** Config: JUCE_WASAPI_EXCLUSIVE
Enables WASAPI audio devices in exclusive mode (Windows Vista and above).
*/
#ifndef JUCE_WASAPI_EXCLUSIVE
#define JUCE_WASAPI_EXCLUSIVE 0
#endif
/** Config: JUCE_DIRECTSOUND
Enables DirectSound audio (MS Windows only).
*/


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/juce_module_info View File

@@ -1,7 +1,7 @@
{
"id": "juce_audio_devices",
"name": "JUCE audio and midi I/O device classes",
"version": "3.0.8",
"version": "3.1.1",
"description": "Classes to play and record from audio and midi i/o devices.",
"website": "http://www.juce.com/juce",
"license": "GPL/Commercial",


+ 6
- 8
libs/juce/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h View File

@@ -139,7 +139,7 @@ public:
//==============================================================================
/** Destructor. */
virtual ~MidiInput();
~MidiInput();
/** Returns the name of this device. */
const String& getName() const noexcept { return name; }
@@ -158,23 +158,21 @@ public:
@see stop
*/
virtual void start();
void start();
/** Stops the device running.
@see start
*/
virtual void stop();
void stop();
protected:
private:
//==============================================================================
String name;
void* internal;
explicit MidiInput (const String& name);
// The input objects are created with the openDevice() method.
explicit MidiInput (const String&);
private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput)
};


+ 12
- 17
libs/juce/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h View File

@@ -82,13 +82,12 @@ public:
//==============================================================================
/** Destructor. */
virtual ~MidiOutput();
~MidiOutput();
/** Makes this device output a midi message.
@see MidiMessage
*/
virtual void sendMessageNow (const MidiMessage& message);
void sendMessageNow (const MidiMessage& message);
//==============================================================================
/** This lets you supply a block of messages that will be sent out at some point
@@ -100,7 +99,7 @@ public:
This will only work if you've already started the thread with startBackgroundThread().
A time is supplied, at which the block of messages should be sent. This time uses
A time is specified, at which the block of messages should be sent. This time uses
the same time base as Time::getMillisecondCounter(), and must be in the future.
The samplesPerSecondForBuffer parameter indicates the number of samples per second
@@ -108,38 +107,34 @@ public:
samplesPerSecondForBuffer value is needed to convert this sample position to a
real time.
*/
virtual void sendBlockOfMessages (const MidiBuffer& buffer,
double millisecondCounterToStartAt,
double samplesPerSecondForBuffer);
void sendBlockOfMessages (const MidiBuffer& buffer,
double millisecondCounterToStartAt,
double samplesPerSecondForBuffer);
/** Gets rid of any midi messages that had been added by sendBlockOfMessages().
*/
virtual void clearAllPendingMessages();
/** Gets rid of any midi messages that had been added by sendBlockOfMessages(). */
void clearAllPendingMessages();
/** Starts up a background thread so that the device can send blocks of data.
Call this to get the device ready, before using sendBlockOfMessages().
*/
virtual void startBackgroundThread();
void startBackgroundThread();
/** Stops the background thread, and clears any pending midi events.
@see startBackgroundThread
*/
virtual void stopBackgroundThread();
void stopBackgroundThread();
protected:
private:
//==============================================================================
void* internal;
CriticalSection lock;
struct PendingMessage;
PendingMessage* firstMessage;
MidiOutput();
MidiOutput(); // These objects are created with the openDevice() method.
void run() override;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput)
};


+ 6
- 6
libs/juce/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp View File

@@ -47,13 +47,13 @@ public:
// this is a total guess about how to calculate the latency, but seems to vaguely agree
// with the devices I've tested.. YMMV
inputLatency = ((javaDevice.minBufferSizeIn * 2) / 3);
outputLatency = ((javaDevice.minBufferSizeOut * 2) / 3);
inputLatency = (javaDevice.minBufferSizeIn * 2) / 3;
outputLatency = (javaDevice.minBufferSizeOut * 2) / 3;
const int longestLatency = jmax (inputLatency, outputLatency);
const int totalLatency = inputLatency + outputLatency;
inputLatency = ((longestLatency * inputLatency) / totalLatency) & ~15;
outputLatency = ((longestLatency * outputLatency) / totalLatency) & ~15;
const int64 longestLatency = jmax (inputLatency, outputLatency);
const int64 totalLatency = inputLatency + outputLatency;
inputLatency = (int) ((longestLatency * inputLatency) / totalLatency) & ~15;
outputLatency = (int) ((longestLatency * outputLatency) / totalLatency) & ~15;
}
~OpenSLAudioIODevice()


+ 21
- 7
libs/juce/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp View File

@@ -30,7 +30,7 @@ namespace
#endif
#if JUCE_ALSA_LOGGING
#define JUCE_ALSA_LOG(dbgtext) { juce::String tempDbgBuf ("ALSA: "); tempDbgBuf << dbgtext; Logger::writeToLog (tempDbgBuf); DBG (tempDbgBuf) }
#define JUCE_ALSA_LOG(dbgtext) { juce::String tempDbgBuf ("ALSA: "); tempDbgBuf << dbgtext; Logger::writeToLog (tempDbgBuf); DBG (tempDbgBuf); }
#define JUCE_CHECKED_RESULT(x) (logErrorMessage (x, __LINE__))
static int logErrorMessage (int err, int lineNum)
@@ -149,7 +149,7 @@ class ALSADevice
{
public:
ALSADevice (const String& devID, bool forInput)
: handle (0),
: handle (nullptr),
bitDepth (16),
numChannelsRunning (0),
latency (0),
@@ -183,16 +183,16 @@ public:
void closeNow()
{
if (handle != 0)
if (handle != nullptr)
{
snd_pcm_close (handle);
handle = 0;
handle = nullptr;
}
}
bool setParameters (unsigned int sampleRate, int numChannels, int bufferSize)
{
if (handle == 0)
if (handle == nullptr)
return false;
JUCE_ALSA_LOG ("ALSADevice::setParameters(" << deviceID << ", "
@@ -644,8 +644,21 @@ public:
{
while (! threadShouldExit())
{
if (inputDevice != nullptr && inputDevice->handle)
if (inputDevice != nullptr && inputDevice->handle != nullptr)
{
if (outputDevice == nullptr || outputDevice->handle == nullptr)
{
JUCE_ALSA_FAILED (snd_pcm_wait (inputDevice->handle, 2000));
if (threadShouldExit())
break;
snd_pcm_sframes_t avail = snd_pcm_avail_update (inputDevice->handle);
if (avail < 0)
JUCE_ALSA_FAILED (snd_pcm_recover (inputDevice->handle, avail, 0));
}
audioIoInProgress = true;
if (! inputDevice->readFromInputDevice (inputChannelBuffer, bufferSize))
@@ -679,7 +692,7 @@ public:
}
}
if (outputDevice != nullptr && outputDevice->handle)
if (outputDevice != nullptr && outputDevice->handle != nullptr)
{
JUCE_ALSA_FAILED (snd_pcm_wait (outputDevice->handle, 2000));
@@ -702,6 +715,7 @@ public:
audioIoInProgress = false;
}
}
audioIoInProgress = false;
}


+ 12
- 3
libs/juce/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp View File

@@ -419,7 +419,7 @@ public:
port.deletePort();
}
void sendMessageNow (const MidiMessage& message)
bool sendMessageNow (const MidiMessage& message)
{
if (message.getRawDataSize() > maxEventSize)
{
@@ -435,12 +435,17 @@ public:
const uint8* data = message.getRawData();
snd_seq_t* seqHandle = port.client->get();
bool success = true;
while (numBytes > 0)
{
const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event);
if (numSent <= 0)
{
success = numSent == 0;
break;
}
numBytes -= numSent;
data += numSent;
@@ -449,11 +454,15 @@ public:
snd_seq_ev_set_subs (&event);
snd_seq_ev_set_direct (&event);
snd_seq_event_output (seqHandle, &event);
if (snd_seq_event_output_direct (seqHandle, &event) < 0)
{
success = false;
break;
}
}
snd_seq_drain_output (seqHandle);
snd_midi_event_reset_encode (midiParser);
return success;
}
private:


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp View File

@@ -543,7 +543,7 @@ public:
// set sample rate
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioDevicePropertyNominalSampleRate;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mScope = kAudioObjectPropertyScopeGlobal;
pa.mElement = kAudioObjectPropertyElementMaster;
Float64 sr = newSampleRate;


+ 65
- 49
libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -123,9 +123,9 @@ struct ASIOSampleFormat
{
switch (bitDepth)
{
case 16: convertInt16ToFloat (static_cast <const char*> (src), dst, byteStride, samps, littleEndian); break;
case 24: convertInt24ToFloat (static_cast <const char*> (src), dst, byteStride, samps, littleEndian); break;
case 32: convertInt32ToFloat (static_cast <const char*> (src), dst, byteStride, samps, littleEndian); break;
case 16: convertInt16ToFloat (static_cast<const char*> (src), dst, byteStride, samps, littleEndian); break;
case 24: convertInt24ToFloat (static_cast<const char*> (src), dst, byteStride, samps, littleEndian); break;
case 32: convertInt32ToFloat (static_cast<const char*> (src), dst, byteStride, samps, littleEndian); break;
default: jassertfalse; break;
}
}
@@ -141,9 +141,9 @@ struct ASIOSampleFormat
{
switch (bitDepth)
{
case 16: convertFloatToInt16 (src, static_cast <char*> (dst), byteStride, samps, littleEndian); break;
case 24: convertFloatToInt24 (src, static_cast <char*> (dst), byteStride, samps, littleEndian); break;
case 32: convertFloatToInt32 (src, static_cast <char*> (dst), byteStride, samps, littleEndian); break;
case 16: convertFloatToInt16 (src, static_cast<char*> (dst), byteStride, samps, littleEndian); break;
case 24: convertFloatToInt24 (src, static_cast<char*> (dst), byteStride, samps, littleEndian); break;
case 32: convertFloatToInt32 (src, static_cast<char*> (dst), byteStride, samps, littleEndian); break;
default: jassertfalse; break;
}
}
@@ -300,7 +300,7 @@ private:
//==============================================================================
class ASIOAudioIODevice;
static ASIOAudioIODevice* volatile currentASIODev[3] = { 0 };
static ASIOAudioIODevice* volatile currentASIODev[16] = { 0 };
extern HWND juce_messageWindowHandle;
@@ -438,8 +438,6 @@ public:
currentBlockSizeSamples = bufferSizeSamples;
currentChansOut.clear();
currentChansIn.clear();
inBuffers.clear (totalNumInputChans + 1);
outBuffers.clear (totalNumOutputChans + 1);
updateSampleRates();
@@ -458,6 +456,13 @@ public:
setSampleRate (sampleRate);
// (need to get this again in case a sample rate change affected the channel count)
err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans);
jassert (err == ASE_OK);
inBuffers.calloc (totalNumInputChans + 8);
outBuffers.calloc (totalNumOutputChans + 8);
if (needToReset)
{
JUCE_ASIO_LOG (" Resetting");
@@ -1320,7 +1325,7 @@ private:
inputFormat[i].convertToFloat (infos[i].buffers[bi], inBuffers[i], samps);
}
currentCallback->audioDeviceIOCallback (const_cast <const float**> (inBuffers.getData()), numActiveInputChans,
currentCallback->audioDeviceIOCallback (const_cast<const float**> (inBuffers.getData()), numActiveInputChans,
outBuffers, numActiveOutputChans, samps);
for (int i = 0; i < numActiveOutputChans; ++i)
@@ -1340,6 +1345,29 @@ private:
asioObject->outputReady();
}
long asioMessagesCallback (long selector, long value)
{
switch (selector)
{
case kAsioSelectorSupported:
if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor)
return 1;
break;
case kAsioBufferSizeChange: JUCE_ASIO_LOG ("kAsioBufferSizeChange"); resetRequest(); return 1;
case kAsioResetRequest: JUCE_ASIO_LOG ("kAsioResetRequest"); resetRequest(); return 1;
case kAsioResyncRequest: JUCE_ASIO_LOG ("kAsioResyncRequest"); resetRequest(); return 1;
case kAsioLatenciesChanged: JUCE_ASIO_LOG ("kAsioLatenciesChanged"); return 1;
case kAsioEngineVersion: return 2;
case kAsioSupportsTimeInfo:
case kAsioSupportsTimeCode: return 0;
}
return 0;
}
//==============================================================================
template <int deviceIndex>
struct ASIOCallbackFunctions
@@ -1360,56 +1388,43 @@ private:
static long JUCE_ASIOCALLBACK asioMessagesCallback (long selector, long value, void*, double*)
{
switch (selector)
{
case kAsioSelectorSupported:
if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest
|| value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor)
return 1;
break;
case kAsioBufferSizeChange: JUCE_ASIO_LOG ("kAsioBufferSizeChange"); return sendResetRequest (deviceIndex);
case kAsioResetRequest: JUCE_ASIO_LOG ("kAsioResetRequest"); return sendResetRequest (deviceIndex);
case kAsioResyncRequest: JUCE_ASIO_LOG ("kAsioResyncRequest"); return sendResetRequest (deviceIndex);
case kAsioLatenciesChanged: JUCE_ASIO_LOG ("kAsioLatenciesChanged"); return 1;
case kAsioEngineVersion: return 2;
case kAsioSupportsTimeInfo:
case kAsioSupportsTimeCode:
return 0;
}
return 0;
return currentASIODev[deviceIndex] != nullptr
? currentASIODev[deviceIndex]->asioMessagesCallback (selector, value)
: 0;
}
static void JUCE_ASIOCALLBACK sampleRateChangedCallback (ASIOSampleRate)
{
sendResetRequest (deviceIndex);
if (currentASIODev[deviceIndex] != nullptr)
currentASIODev[deviceIndex]->resetRequest();
}
static long sendResetRequest (int index)
static void setCallbacks (ASIOCallbacks& callbacks) noexcept
{
if (currentASIODev[index] != nullptr)
currentASIODev[index]->resetRequest();
return 1;
callbacks.bufferSwitch = &bufferSwitchCallback;
callbacks.asioMessage = &asioMessagesCallback;
callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback;
callbacks.sampleRateDidChange = &sampleRateChangedCallback;
}
static void setCallbacks (ASIOCallbacks& callbacks)
static void setCallbacksForDevice (ASIOCallbacks& callbacks, ASIOAudioIODevice* device) noexcept
{
callbacks.bufferSwitch = &bufferSwitchCallback;
callbacks.asioMessage = &asioMessagesCallback;
callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback;
callbacks.sampleRateDidChange = &sampleRateChangedCallback;
if (currentASIODev[deviceIndex] == device)
setCallbacks (callbacks);
else
ASIOCallbackFunctions<deviceIndex + 1>::setCallbacksForDevice (callbacks, device);
}
};
void setCallbackFunctions()
template <>
struct ASIOCallbackFunctions <sizeof(currentASIODev) / sizeof(currentASIODev[0])>
{
static void setCallbacksForDevice (ASIOCallbacks&, ASIOAudioIODevice*) noexcept {}
};
void setCallbackFunctions() noexcept
{
if (currentASIODev[0] == this) ASIOCallbackFunctions<0>::setCallbacks (callbacks);
else if (currentASIODev[1] == this) ASIOCallbackFunctions<1>::setCallbacks (callbacks);
else if (currentASIODev[2] == this) ASIOCallbackFunctions<2>::setCallbacks (callbacks);
else jassertfalse;
ASIOCallbackFunctions<0>::setCallbacksForDevice (callbacks, this);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODevice)
@@ -1503,15 +1518,16 @@ public:
jassert (inputDeviceName == outputDeviceName || outputDeviceName.isEmpty() || inputDeviceName.isEmpty());
jassert (hasScanned); // need to call scanForDevices() before doing this
const int index = deviceNames.indexOf (outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName);
const String deviceName (outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName);
const int index = deviceNames.indexOf (deviceName);
if (index >= 0)
{
const int freeSlot = findFreeSlot();
if (freeSlot >= 0)
return new ASIOAudioIODevice (this, outputDeviceName,
return new ASIOAudioIODevice (this, deviceName,
classIds.getReference (index), freeSlot);
}


+ 1
- 1
libs/juce/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp View File

@@ -1255,7 +1255,7 @@ private:
DSoundDeviceList deviceList;
bool hasScanned;
void systemDeviceChanged()
void systemDeviceChanged() override
{
DSoundDeviceList newList;
newList.scan();


+ 324
- 140
libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp View File

@@ -45,6 +45,7 @@ void logFailure (HRESULT hr)
{
case E_POINTER: m = "E_POINTER"; break;
case E_INVALIDARG: m = "E_INVALIDARG"; break;
case E_NOINTERFACE: m = "E_NOINTERFACE"; break;
#define JUCE_WASAPI_ERR(desc, n) \
case MAKE_HRESULT(1, 0x889, n): m = #desc; break;
@@ -126,7 +127,11 @@ enum EDataFlow
eAll = (eCapture + 1)
};
enum { DEVICE_STATE_ACTIVE = 1 };
enum
{
DEVICE_STATE_ACTIVE = 1,
AUDCLNT_BUFFERFLAGS_SILENT = 2
};
JUCE_IUNKNOWNCLASS (IPropertyStore, "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99")
{
@@ -328,6 +333,11 @@ int refTimeToSamples (const REFERENCE_TIME& t, const double sampleRate) noexcept
return roundToInt (sampleRate * ((double) t) * 0.0000001);
}
REFERENCE_TIME samplesToRefTime (const int numSamples, const double sampleRate) noexcept
{
return (REFERENCE_TIME) ((numSamples * 10000.0 * 1000.0 / sampleRate) + 0.5);
}
void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* const src) noexcept
{
memcpy (&dest, src, src->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? sizeof (WAVEFORMATEXTENSIBLE)
@@ -348,9 +358,12 @@ public:
defaultBufferSize (0),
latencySamples (0),
useExclusiveMode (exclusiveMode),
actualBufferSize (0),
bytesPerSample (0),
bytesPerFrame (0),
sampleRateHasChanged (false)
{
clientEvent = CreateEvent (0, false, false, _T("JuceWASAPI"));
clientEvent = CreateEvent (nullptr, false, false, nullptr);
ComSmartPtr<IAudioClient> tempClient (createClient());
if (tempClient == nullptr)
@@ -376,16 +389,24 @@ public:
rates.addUsingDefaultSort (defaultSampleRate);
static const int ratesToTest[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
if (useExclusiveMode
&& findSupportedFormat (tempClient, defaultSampleRate, format.dwChannelMask, format))
{
// Got a format that is supported by the device so we can ask what sample rates are supported (in whatever format)
}
static const int ratesToTest[] = { 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 };
for (int i = 0; i < numElementsInArray (ratesToTest); ++i)
{
if (ratesToTest[i] == defaultSampleRate)
if (rates.contains (ratesToTest[i]))
continue;
format.Format.nSamplesPerSec = (DWORD) ratesToTest[i];
format.Format.nSamplesPerSec = (DWORD) ratesToTest[i];
format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nChannels * format.Format.wBitsPerSample / 8);
if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED,
if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE
: AUDCLNT_SHAREMODE_SHARED,
(WAVEFORMATEX*) &format, 0)))
if (! rates.contains (ratesToTest[i]))
rates.addUsingDefaultSort (ratesToTest[i]);
@@ -400,7 +421,7 @@ public:
bool isOk() const noexcept { return defaultBufferSize > 0 && defaultSampleRate > 0; }
bool openClient (const double newSampleRate, const BigInteger& newChannels)
bool openClient (const double newSampleRate, const BigInteger& newChannels, const int bufferSizeSamples)
{
sampleRate = newSampleRate;
channels = newChannels;
@@ -413,8 +434,7 @@ public:
client = createClient();
if (client != nullptr
&& (tryInitialisingWithFormat (true, 4) || tryInitialisingWithFormat (false, 4)
|| tryInitialisingWithFormat (false, 3) || tryInitialisingWithFormat (false, 2)))
&& tryInitialisingWithBufferSize (bufferSizeSamples))
{
sampleRateHasChanged = false;
@@ -465,7 +485,7 @@ public:
BigInteger channels;
Array<int> channelMaps;
UINT32 actualBufferSize;
int bytesPerSample;
int bytesPerSample, bytesPerFrame;
bool sampleRateHasChanged;
virtual void updateFormat (bool isFloat) = 0;
@@ -536,12 +556,19 @@ private:
return client;
}
bool tryInitialisingWithFormat (const bool useFloat, const int bytesPerSampleToTry)
struct AudioSampleFormat
{
bool useFloat;
int bitsPerSampleToTry;
int bytesPerSampleContainer;
};
bool tryFormat (const AudioSampleFormat sampleFormat, IAudioClient* clientToUse, double sampleRate,
DWORD mixFormatChannelMask, WAVEFORMATEXTENSIBLE& format) const
{
WAVEFORMATEXTENSIBLE format;
zerostruct (format);
if (numChannels <= 2 && bytesPerSampleToTry <= 2)
if (numChannels <= 2 && sampleFormat.bitsPerSampleToTry <= 16)
{
format.Format.wFormatTag = WAVE_FORMAT_PCM;
}
@@ -553,45 +580,97 @@ private:
format.Format.nSamplesPerSec = (DWORD) sampleRate;
format.Format.nChannels = (WORD) numChannels;
format.Format.wBitsPerSample = (WORD) (8 * bytesPerSampleToTry);
format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * numChannels * bytesPerSampleToTry);
format.Format.nBlockAlign = (WORD) (numChannels * bytesPerSampleToTry);
format.SubFormat = useFloat ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM;
format.Samples.wValidBitsPerSample = format.Format.wBitsPerSample;
format.Format.wBitsPerSample = (WORD) (8 * sampleFormat.bytesPerSampleContainer);
format.Samples.wValidBitsPerSample = (WORD) (sampleFormat.bitsPerSampleToTry);
format.Format.nBlockAlign = (WORD) (format.Format.nChannels * format.Format.wBitsPerSample / 8);
format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nBlockAlign);
format.SubFormat = sampleFormat.useFloat ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM;
format.dwChannelMask = mixFormatChannelMask;
WAVEFORMATEXTENSIBLE* nearestFormat = nullptr;
HRESULT hr = client->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE
: AUDCLNT_SHAREMODE_SHARED,
(WAVEFORMATEX*) &format,
useExclusiveMode ? nullptr : (WAVEFORMATEX**) &nearestFormat);
HRESULT hr = clientToUse->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE
: AUDCLNT_SHAREMODE_SHARED,
(WAVEFORMATEX*) &format,
useExclusiveMode ? nullptr : (WAVEFORMATEX**) &nearestFormat);
logFailure (hr);
if (hr == S_FALSE && format.Format.nSamplesPerSec == nearestFormat->Format.nSamplesPerSec)
{
copyWavFormat (format, (WAVEFORMATEX*) nearestFormat);
copyWavFormat (format, (const WAVEFORMATEX*) nearestFormat);
hr = S_OK;
}
CoTaskMemFree (nearestFormat);
return check (hr);
}
REFERENCE_TIME defaultPeriod = 0, minPeriod = 0;
if (useExclusiveMode)
check (client->GetDevicePeriod (&defaultPeriod, &minPeriod));
bool findSupportedFormat (IAudioClient* clientToUse, double sampleRate,
DWORD mixFormatChannelMask, WAVEFORMATEXTENSIBLE& format) const
{
static const AudioSampleFormat formats[] =
{
{ true, 32, 4 },
{ false, 32, 4 },
{ false, 24, 4 },
{ false, 24, 3 },
{ false, 20, 4 },
{ false, 20, 3 },
{ false, 16, 2 }
};
for (int i = 0; i < numElementsInArray (formats); ++i)
if (tryFormat (formats[i], clientToUse, sampleRate, mixFormatChannelMask, format))
return true;
return false;
}
GUID session;
if (hr == S_OK
&& check (client->Initialize (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED,
0x40000 /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/,
defaultPeriod, defaultPeriod, (WAVEFORMATEX*) &format, &session)))
bool tryInitialisingWithBufferSize (const int bufferSizeSamples)
{
WAVEFORMATEXTENSIBLE format;
if (findSupportedFormat (client, sampleRate, mixFormatChannelMask, format))
{
actualNumChannels = format.Format.nChannels;
const bool isFloat = format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && format.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
bytesPerSample = format.Format.wBitsPerSample / 8;
REFERENCE_TIME defaultPeriod = 0, minPeriod = 0;
updateFormat (isFloat);
return true;
check (client->GetDevicePeriod (&defaultPeriod, &minPeriod));
if (useExclusiveMode && bufferSizeSamples > 0)
defaultPeriod = jmax (minPeriod, samplesToRefTime (bufferSizeSamples, format.Format.nSamplesPerSec));
for (;;)
{
GUID session;
HRESULT hr = client->Initialize (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED,
0x40000 /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/,
defaultPeriod, useExclusiveMode ? defaultPeriod : 0, (WAVEFORMATEX*) &format, &session);
if (check (hr))
{
actualNumChannels = format.Format.nChannels;
const bool isFloat = format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && format.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
bytesPerSample = format.Format.wBitsPerSample / 8;
bytesPerFrame = format.Format.nBlockAlign;
updateFormat (isFloat);
return true;
}
// Handle the "alignment dance" : http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875(v=vs.85).aspx (see Remarks)
if (hr != MAKE_HRESULT (1, 0x889, 0x19)) // AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED
break;
UINT32 numFrames = 0;
if (! check (client->GetBufferSize (&numFrames)))
break;
// Recreate client
client = nullptr;
client = createClient();
defaultPeriod = samplesToRefTime (numFrames, format.Format.nSamplesPerSec);
}
}
return false;
@@ -615,12 +694,9 @@ public:
close();
}
bool open (const double newSampleRate, const BigInteger& newChannels)
bool open (const double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
{
reservoirSize = 0;
reservoirCapacity = 16384;
reservoir.setSize (actualNumChannels * reservoirCapacity * sizeof (float));
return openClient (newSampleRate, newChannels)
return openClient (newSampleRate, newChannels, bufferSizeSamples)
&& (numChannels == 0 || check (client->GetService (__uuidof (IAudioCaptureClient),
(void**) captureClient.resetAndGetPointerAddress())));
}
@@ -630,88 +706,129 @@ public:
closeClient();
captureClient = nullptr;
reservoir.reset();
reservoirReadPos = reservoirWritePos = 0;
}
template<class SourceType>
void updateFormatWithType (SourceType*)
void updateFormatWithType (SourceType*) noexcept
{
typedef AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> NativeType;
converter = new AudioData::ConverterInstance<AudioData::Pointer<SourceType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, NativeType> (actualNumChannels, 1);
}
void updateFormat (bool isFloat)
void updateFormat (bool isFloat) override
{
if (isFloat) updateFormatWithType ((AudioData::Float32*) nullptr);
else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) nullptr);
else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) nullptr);
else updateFormatWithType ((AudioData::Int16*) nullptr);
}
bool start (const int userBufferSize)
{
reservoirSize = actualBufferSize + userBufferSize;
reservoirMask = nextPowerOfTwo (reservoirSize) - 1;
reservoir.setSize ((reservoirMask + 1) * bytesPerFrame, true);
reservoirReadPos = reservoirWritePos = 0;
if (! check (client->Start()))
return false;
purgeInputBuffers();
return true;
}
void purgeInputBuffers()
{
if (isFloat) updateFormatWithType ((AudioData::Float32*) 0);
else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) 0);
else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) 0);
else updateFormatWithType ((AudioData::Int16*) 0);
uint8* inputData;
UINT32 numSamplesAvailable;
DWORD flags;
while (captureClient->GetBuffer (&inputData, &numSamplesAvailable, &flags, nullptr, nullptr)
!= MAKE_HRESULT (0, 0x889, 0x1) /* AUDCLNT_S_BUFFER_EMPTY */)
captureClient->ReleaseBuffer (numSamplesAvailable);
}
void copyBuffers (float** destBuffers, int numDestBuffers, int bufferSize, Thread& thread)
int getNumSamplesInReservoir() const noexcept { return reservoirWritePos - reservoirReadPos; }
void handleDeviceBuffer()
{
if (numChannels <= 0)
return;
int offset = 0;
uint8* inputData;
UINT32 numSamplesAvailable;
DWORD flags;
while (bufferSize > 0)
while (check (captureClient->GetBuffer (&inputData, &numSamplesAvailable, &flags, nullptr, nullptr)) && numSamplesAvailable > 0)
{
if (reservoirSize > 0) // There's stuff in the reservoir, so use that...
int samplesLeft = (int) numSamplesAvailable;
while (samplesLeft > 0)
{
const int samplesToDo = jmin (bufferSize, (int) reservoirSize);
const int localWrite = reservoirWritePos & reservoirMask;
const int samplesToDo = jmin (samplesLeft, reservoirMask + 1 - localWrite);
const int samplesToDoBytes = samplesToDo * bytesPerFrame;
for (int i = 0; i < numDestBuffers; ++i)
converter->convertSamples (destBuffers[i] + offset, 0, reservoir.getData(), channelMaps.getUnchecked(i), samplesToDo);
void* reservoirPtr = addBytesToPointer (reservoir.getData(), localWrite * bytesPerFrame);
bufferSize -= samplesToDo;
offset += samplesToDo;
reservoirSize = 0;
if ((flags & AUDCLNT_BUFFERFLAGS_SILENT) != 0)
zeromem (reservoirPtr, samplesToDoBytes);
else
memcpy (reservoirPtr, inputData, samplesToDoBytes);
reservoirWritePos += samplesToDo;
inputData += samplesToDoBytes;
samplesLeft -= samplesToDo;
}
else
{
UINT32 packetLength = 0;
if (! check (captureClient->GetNextPacketSize (&packetLength)))
break;
if (packetLength == 0)
{
if (thread.threadShouldExit()
|| WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT)
break;
if (getNumSamplesInReservoir() > reservoirSize)
reservoirReadPos = reservoirWritePos - reservoirSize;
continue;
}
captureClient->ReleaseBuffer (numSamplesAvailable);
}
}
uint8* inputData;
UINT32 numSamplesAvailable;
DWORD flags;
void copyBuffersFromReservoir (float** destBuffers, int numDestBuffers, int bufferSize)
{
if ((numChannels <= 0 && bufferSize == 0) || reservoir.getSize() == 0)
return;
if (check (captureClient->GetBuffer (&inputData, &numSamplesAvailable, &flags, 0, 0)))
{
const int samplesToDo = jmin (bufferSize, (int) numSamplesAvailable);
int offset = jmax (0, bufferSize - getNumSamplesInReservoir());
for (int i = 0; i < numDestBuffers; ++i)
converter->convertSamples (destBuffers[i] + offset, 0, inputData, channelMaps.getUnchecked(i), samplesToDo);
if (offset > 0)
{
for (int i = 0; i < numDestBuffers; ++i)
zeromem (destBuffers[i], offset * sizeof (float));
bufferSize -= samplesToDo;
offset += samplesToDo;
bufferSize -= offset;
reservoirReadPos -= offset / 2;
}
if (samplesToDo < (int) numSamplesAvailable)
{
reservoirSize = jmin ((int) (numSamplesAvailable - samplesToDo), reservoirCapacity);
memcpy ((uint8*) reservoir.getData(), inputData + bytesPerSample * actualNumChannels * samplesToDo,
(size_t) (bytesPerSample * actualNumChannels * reservoirSize));
}
while (bufferSize > 0)
{
const int localRead = reservoirReadPos & reservoirMask;
captureClient->ReleaseBuffer (numSamplesAvailable);
}
}
const int samplesToDo = jmin (bufferSize, getNumSamplesInReservoir(), reservoirMask + 1 - localRead);
if (samplesToDo <= 0)
break;
const int reservoirOffset = localRead * bytesPerFrame;
for (int i = 0; i < numDestBuffers; ++i)
converter->convertSamples (destBuffers[i] + offset, 0, addBytesToPointer (reservoir.getData(), reservoirOffset), channelMaps.getUnchecked(i), samplesToDo);
bufferSize -= samplesToDo;
offset += samplesToDo;
reservoirReadPos += samplesToDo;
}
}
ComSmartPtr<IAudioCaptureClient> captureClient;
MemoryBlock reservoir;
int reservoirSize, reservoirCapacity;
int reservoirSize, reservoirMask;
volatile int reservoirReadPos, reservoirWritePos;
ScopedPointer<AudioData::Converter> converter;
private:
@@ -732,10 +849,11 @@ public:
close();
}
bool open (const double newSampleRate, const BigInteger& newChannels)
bool open (const double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
{
return openClient (newSampleRate, newChannels)
&& (numChannels == 0 || check (client->GetService (__uuidof (IAudioRenderClient), (void**) renderClient.resetAndGetPointerAddress())));
return openClient (newSampleRate, newChannels, bufferSizeSamples)
&& (numChannels == 0 || check (client->GetService (__uuidof (IAudioRenderClient),
(void**) renderClient.resetAndGetPointerAddress())));
}
void close()
@@ -751,15 +869,42 @@ public:
converter = new AudioData::ConverterInstance<NativeType, AudioData::Pointer<DestType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst> > (1, actualNumChannels);
}
void updateFormat (bool isFloat)
void updateFormat (bool isFloat) override
{
if (isFloat) updateFormatWithType ((AudioData::Float32*) nullptr);
else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) nullptr);
else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) nullptr);
else updateFormatWithType ((AudioData::Int16*) nullptr);
}
bool start()
{
if (isFloat) updateFormatWithType ((AudioData::Float32*) 0);
else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) 0);
else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) 0);
else updateFormatWithType ((AudioData::Int16*) 0);
int samplesToDo = getNumSamplesAvailableToCopy();
uint8* outputData;
if (check (renderClient->GetBuffer (samplesToDo, &outputData)))
renderClient->ReleaseBuffer (samplesToDo, AUDCLNT_BUFFERFLAGS_SILENT);
return check (client->Start());
}
int getNumSamplesAvailableToCopy() const
{
if (numChannels <= 0)
return 0;
if (! useExclusiveMode)
{
UINT32 padding = 0;
if (check (client->GetCurrentPadding (&padding)))
return actualBufferSize - (int) padding;
}
return actualBufferSize;
}
void copyBuffers (const float** const srcBuffers, const int numSrcBuffers, int bufferSize, Thread& thread)
void copyBuffers (const float** const srcBuffers, const int numSrcBuffers, int bufferSize,
WASAPIInputDevice* inputDevice, Thread& thread)
{
if (numChannels <= 0)
return;
@@ -768,22 +913,25 @@ public:
while (bufferSize > 0)
{
UINT32 padding = 0;
if (! check (client->GetCurrentPadding (&padding)))
return;
// This is needed in order not to drop any input data if the output device endpoint buffer was full
if ((! useExclusiveMode) && inputDevice != nullptr
&& WaitForSingleObject (inputDevice->clientEvent, 0) == WAIT_OBJECT_0)
inputDevice->handleDeviceBuffer();
int samplesToDo = useExclusiveMode ? bufferSize
: jmin ((int) (actualBufferSize - padding), bufferSize);
int samplesToDo = jmin (getNumSamplesAvailableToCopy(), bufferSize);
if (samplesToDo <= 0)
if (samplesToDo == 0)
{
if (thread.threadShouldExit()
|| WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT)
break;
// This can ONLY occur in non-exclusive mode
if (! thread.threadShouldExit() && WaitForSingleObject (clientEvent, 1000) == WAIT_OBJECT_0)
continue;
continue;
break;
}
if (useExclusiveMode && WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT)
break;
uint8* outputData = nullptr;
if (check (renderClient->GetBuffer ((UINT32) samplesToDo, &outputData)))
{
@@ -791,10 +939,10 @@ public:
converter->convertSamples (outputData, channelMaps.getUnchecked(i), srcBuffers[i] + offset, 0, samplesToDo);
renderClient->ReleaseBuffer ((UINT32) samplesToDo, 0);
offset += samplesToDo;
bufferSize -= samplesToDo;
}
bufferSize -= samplesToDo;
offset += samplesToDo;
}
}
@@ -812,13 +960,14 @@ class WASAPIAudioIODevice : public AudioIODevice,
{
public:
WASAPIAudioIODevice (const String& deviceName,
const String& outputDeviceId_,
const String& inputDeviceId_,
const String& typeName,
const String& outputDeviceID,
const String& inputDeviceID,
const bool exclusiveMode)
: AudioIODevice (deviceName, "Windows Audio"),
: AudioIODevice (deviceName, typeName),
Thread ("Juce WASAPI"),
outputDeviceId (outputDeviceId_),
inputDeviceId (inputDeviceId_),
outputDeviceId (outputDeviceID),
inputDeviceId (inputDeviceID),
useExclusiveMode (exclusiveMode),
isOpen_ (false),
isStarted (false),
@@ -932,19 +1081,33 @@ public:
lastKnownInputChannels = inputChannels;
lastKnownOutputChannels = outputChannels;
if (inputDevice != nullptr && ! inputDevice->open (currentSampleRate, inputChannels))
if (inputDevice != nullptr && ! inputDevice->open (currentSampleRate, inputChannels, bufferSizeSamples))
{
lastError = TRANS("Couldn't open the input device!");
return lastError;
}
if (outputDevice != nullptr && ! outputDevice->open (currentSampleRate, outputChannels))
if (outputDevice != nullptr && ! outputDevice->open (currentSampleRate, outputChannels, bufferSizeSamples))
{
close();
lastError = TRANS("Couldn't open the output device!");
return lastError;
}
if (useExclusiveMode)
{
// This is to make sure that the callback uses actualBufferSize in case of exclusive mode
if (inputDevice != nullptr && outputDevice != nullptr && inputDevice->actualBufferSize != outputDevice->actualBufferSize)
{
close();
lastError = TRANS("Couldn't open the output device (buffer size mismatch)");
return lastError;
}
currentBufferSizeSamples = outputDevice != nullptr ? outputDevice->actualBufferSize
: inputDevice->actualBufferSize;
}
if (inputDevice != nullptr) ResetEvent (inputDevice->clientEvent);
if (outputDevice != nullptr) ResetEvent (outputDevice->clientEvent);
@@ -955,7 +1118,7 @@ public:
{
latencyIn = (int) (inputDevice->latencySamples + currentBufferSizeSamples);
if (! check (inputDevice->client->Start()))
if (! inputDevice->start (currentBufferSizeSamples))
{
close();
lastError = TRANS("Couldn't start the input device!");
@@ -967,7 +1130,7 @@ public:
{
latencyOut = (int) (outputDevice->latencySamples + currentBufferSizeSamples);
if (! check (outputDevice->client->Start()))
if (! outputDevice->start())
{
close();
lastError = TRANS("Couldn't start the output device!");
@@ -1056,34 +1219,48 @@ public:
const int bufferSize = currentBufferSizeSamples;
const int numInputBuffers = getActiveInputChannels().countNumberOfSetBits();
const int numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits();
bool sampleRateChanged = false;
bool sampleRateHasChanged = false;
AudioSampleBuffer ins (jmax (1, numInputBuffers), bufferSize + 32);
AudioSampleBuffer outs (jmax (1, numOutputBuffers), bufferSize + 32);
float** const inputBuffers = ins.getArrayOfWritePointers();
float** const outputBuffers = outs.getArrayOfWritePointers();
ins.clear();
outs.clear();
while (! threadShouldExit())
{
if (inputDevice != nullptr)
{
inputDevice->copyBuffers (inputBuffers, numInputBuffers, bufferSize, *this);
if (outputDevice == nullptr)
{
if (WaitForSingleObject (inputDevice->clientEvent, 1000) == WAIT_TIMEOUT)
break;
if (threadShouldExit())
break;
inputDevice->handleDeviceBuffer();
if (inputDevice->getNumSamplesInReservoir() < bufferSize)
continue;
}
else
{
if (useExclusiveMode && WaitForSingleObject (inputDevice->clientEvent, 0) == WAIT_OBJECT_0)
inputDevice->handleDeviceBuffer();
}
inputDevice->copyBuffersFromReservoir (inputBuffers, numInputBuffers, bufferSize);
if (inputDevice->sampleRateHasChanged)
{
sampleRateChanged = true;
sampleRateHasChanged = true;
sampleRateChangedByOutput = false;
}
}
{
const ScopedLock sl (startStopLock);
const ScopedTryLock sl (startStopLock);
if (isStarted)
if (sl.isLocked() && isStarted)
callback->audioDeviceIOCallback (const_cast<const float**> (inputBuffers), numInputBuffers,
outputBuffers, numOutputBuffers, bufferSize);
else
@@ -1092,16 +1269,18 @@ public:
if (outputDevice != nullptr)
{
outputDevice->copyBuffers (const_cast<const float**> (outputBuffers), numOutputBuffers, bufferSize, *this);
// Note that this function is handed the input device so it can check for the event and make sure
// the input reservoir is filled up correctly even when bufferSize > device actualBufferSize
outputDevice->copyBuffers (const_cast<const float**> (outputBuffers), numOutputBuffers, bufferSize, inputDevice, *this);
if (outputDevice->sampleRateHasChanged)
{
sampleRateChanged = true;
sampleRateHasChanged = true;
sampleRateChangedByOutput = true;
}
}
if (sampleRateChanged)
if (sampleRateHasChanged)
{
triggerAsyncUpdate();
break; // Quit the thread... will restart it later!
@@ -1208,9 +1387,10 @@ class WASAPIAudioIODeviceType : public AudioIODeviceType,
private DeviceChangeDetector
{
public:
WASAPIAudioIODeviceType()
: AudioIODeviceType ("Windows Audio"),
WASAPIAudioIODeviceType (bool exclusive)
: AudioIODeviceType (exclusive ? "Windows Audio (Exclusive Mode)" : "Windows Audio"),
DeviceChangeDetector (L"Windows Audio"),
exclusiveMode (exclusive),
hasScanned (false)
{
}
@@ -1267,7 +1447,6 @@ public:
{
jassert (hasScanned); // need to call scanForDevices() before doing this
const bool useExclusiveMode = false;
ScopedPointer<WASAPIAudioIODevice> device;
const int outputIndex = outputDeviceNames.indexOf (outputDeviceName);
@@ -1277,9 +1456,10 @@ public:
{
device = new WASAPIAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName,
getTypeName(),
outputDeviceIds [outputIndex],
inputDeviceIds [inputIndex],
useExclusiveMode);
exclusiveMode);
if (! device->initialise())
device = nullptr;
@@ -1293,7 +1473,7 @@ public:
StringArray inputDeviceNames, inputDeviceIds;
private:
bool hasScanned;
bool exclusiveMode, hasScanned;
ComSmartPtr<IMMDeviceEnumerator> enumerator;
//==============================================================================
@@ -1418,7 +1598,7 @@ private:
}
//==============================================================================
void systemDeviceChanged()
void systemDeviceChanged() override
{
StringArray newOutNames, newInNames, newOutIds, newInIds;
scan (newOutNames, newInNames, newOutIds, newInIds);
@@ -1493,12 +1673,16 @@ struct MMDeviceMasterVolume
}
//==============================================================================
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI()
AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool exclusiveMode)
{
if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista)
return new WasapiClasses::WASAPIAudioIODeviceType();
#if ! JUCE_WASAPI_EXCLUSIVE
if (exclusiveMode)
return nullptr;
#endif
return nullptr;
return SystemStats::getOperatingSystemType() >= SystemStats::WinVista
? new WasapiClasses::WASAPIAudioIODeviceType (exclusiveMode)
: nullptr;
}
//==============================================================================


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/all.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/alloc.h View File

@@ -1,6 +1,6 @@
/* alloc - Convenience routines for safely allocating memory
* Copyright (C) 2007-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,7 +33,7 @@
#ifndef FLAC__SHARE__ALLOC_H
#define FLAC__SHARE__ALLOC_H
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/assert.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/callback.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 20
- 15
libs/juce/source/modules/juce_audio_formats/codecs/flac/compat.h View File

@@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2012 Xiph.org Foundation
* Copyright (C) 2012-2014 Xiph.org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -73,23 +73,25 @@
#endif
#if defined(_MSC_VER)
#if _MSC_VER < 1500
/* Visual Studio 2008 has restrict. */
#define restrict __restrict
#endif
#define inline __inline
#endif
/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
#ifdef _MSC_VER
#define FLAC__U64L(x) x
#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
/* MSVS generates VERY slow 32-bit code with __restrict */
#define flac_restrict __restrict
#elif defined __GNUC__
#define flac_restrict __restrict__
#else
#define FLAC__U64L(x) x##LLU
#define flac_restrict
#endif
#define FLAC__U64L(x) x##ULL
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
#define FLAC__STRCASECMP stricmp
#define FLAC__STRNCASECMP strnicmp
#else
#define FLAC__STRCASECMP strcasecmp
#define FLAC__STRNCASECMP strncasecmp
#endif
@@ -139,6 +141,7 @@
#ifdef _WIN32
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */
#include "win_utf8_io.h"
#define flac_printf printf_utf8
#define flac_fprintf fprintf_utf8
@@ -160,12 +163,7 @@
#define flac_utime utime
#define flac_unlink unlink
#define flac_rename rename
#ifdef _WIN32
#define flac_stat _stat64
#else
#define flac_stat stat
#endif
#endif
@@ -177,8 +175,14 @@
#define flac_fstat fstat
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
/* FLAC needs to compile and work correctly on systems with a norrmal ISO C99
/* FLAC needs to compile and work correctly on systems with a normal ISO C99
* snprintf as well as Microsoft Visual Studio which has an non-standards
* conformant snprint_s function.
*
@@ -188,6 +192,7 @@
extern "C" {
#endif
int flac_snprintf(char *str, size_t size, const char *fmt, ...);
int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
#ifdef __cplusplus
};
#endif


+ 28
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/endswap.h View File

@@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2012 Xiph.org Foundation
* Copyright (C) 2012-2014 Xiph.org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,20 +33,46 @@
#if HAVE_BSWAP32 /* GCC and Clang */
/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */
#if ! HAVE_BSWAP16
static inline unsigned short __builtin_bswap16(unsigned short a)
{
return (a<<8)|(a>>8);
}
#endif
#define ENDSWAP_16(x) (__builtin_bswap16 (x))
#define ENDSWAP_32(x) (__builtin_bswap32 (x))
#elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */
#define ENDSWAP_16(x) (_byteswap_ushort (x))
#define ENDSWAP_32(x) (_byteswap_ulong (x))
#elif defined HAVE_BYTESWAP_H /* Linux */
#include <byteswap.h>
#define ENDSWAP_16(x) (bswap_16 (x))
#define ENDSWAP_32(x) (bswap_32 (x))
#else
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24))
#endif
/* Host to little-endian byte swapping. */
#if CPU_IS_BIG_ENDIAN
#define H2LE_16(x) ENDSWAP_16 (x)
#define H2LE_32(x) ENDSWAP_32 (x)
#else
#define H2LE_16(x) (x)
#define H2LE_32(x) (x)
#endif

+ 3
- 3
libs/juce/source/modules/juce_audio_formats/codecs/flac/export.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#elif defined(_MSC_VER)
#ifdef FLAC_API_EXPORTS
#define FLAC_API _declspec(dllexport)
#define FLAC_API __declspec(dllexport)
#else
#define FLAC_API _declspec(dllimport)
#define FLAC_API __declspec(dllimport)
#endif
#elif defined(FLAC__USE_VISIBILITY_ATTR)


+ 4
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/format.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -509,9 +509,11 @@ typedef enum {
FLAC__METADATA_TYPE_PICTURE = 6,
/**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */
FLAC__METADATA_TYPE_UNDEFINED = 7
FLAC__METADATA_TYPE_UNDEFINED = 7,
/**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */
FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE,
/**< No type will ever be greater than this. There is not enough room in the protocol block. */
} FLAC__MetadataType;
/** Maps a FLAC__MetadataType to a C string.


+ 2
- 3
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,12 +30,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "include/private/bitmath.h"
#include "../assert.h"
/* An example of what FLAC__bitmath_silog2() computes:
*


+ 6
- 10
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -73,7 +73,6 @@
*/
static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */
/* WATCHOUT: assembly routines rely on the order in which these fields are declared */
struct FLAC__BitReader {
/* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
/* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
@@ -87,7 +86,6 @@ struct FLAC__BitReader {
unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
FLAC__BitReaderReadCallback read_callback;
void *client_data;
FLAC__CPUInfo cpu_info;
};
static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word)
@@ -119,8 +117,7 @@ static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word)
br->crc16_align = 0;
}
/* would be static except it needs to be called by asm routines */
FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
{
unsigned start, end;
size_t bytes;
@@ -231,7 +228,7 @@ void FLAC__bitreader_delete(FLAC__BitReader *br)
*
***********************************************************************/
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd)
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd)
{
FLAC__ASSERT(0 != br);
@@ -243,7 +240,6 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__Bi
return false;
br->read_callback = rcb;
br->client_data = cd;
br->cpu_info = cpu;
return true;
}
@@ -1048,9 +1044,9 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v
return true;
}
/* These functions a declared inline in this file but are also callable as
/* These functions are declared inline in this file but are also callable as
* externs from elsewhere.
* According to the C99 sepc, section 6.7.4, simply providing a function
* According to the C99 spec, section 6.7.4, simply providing a function
* prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To


+ 5
- 31
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -47,8 +47,7 @@
/* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
/* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */
#define FLAC__BYTES_PER_WORD 4
#undef FLAC__BITS_PER_WORD
#define FLAC__BITS_PER_WORD 32
#define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD)
#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
/* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */
#if WORDS_BIGENDIAN
@@ -524,28 +523,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL
msbits = uval >> parameter;
#if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */
if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */
/* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */
bw->bits = bw->bits + msbits + lsbits;
uval |= mask1; /* set stop bit */
uval &= mask2; /* mask off unused top bits */
/* NOT: bw->accum <<= msbits + lsbits because msbits+lsbits could be 32, then the shift would be a NOP */
bw->accum <<= msbits;
bw->accum <<= lsbits;
bw->accum |= uval;
if(bw->bits == FLAC__BITS_PER_WORD) {
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
bw->bits = 0;
/* burying the capacity check down here means we have to grow the buffer a little if there are more vals to do */
if(bw->capacity <= bw->words && nvals > 1 && !bitwriter_grow_(bw, 1)) {
FLAC__ASSERT(bw->capacity == bw->words);
return false;
}
}
}
else {
#elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */
if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */
/* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */
bw->bits = bw->bits + msbits + lsbits;
@@ -555,7 +532,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL
bw->accum |= uval;
}
else {
#endif
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
/* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */
if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits))
@@ -610,9 +586,7 @@ break1:
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
bw->accum = uval;
}
#if 1
}
#endif
vals++;
nvals--;
}
@@ -853,9 +827,9 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw)
return true;
}
/* These functions a declared inline in this file but are also callable as
/* These functions are declared inline in this file but are also callable as
* externs from elsewhere.
* According to the C99 sepc, section 6.7.4, simply providing a function
* According to the C99 spec, section 6.7.4, simply providing a function
* prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To


+ 338
- 267
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,47 +30,47 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "include/private/cpu.h"
#include <stdlib.h>
#include <stdio.h>
#if 0
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#endif
#if defined FLAC__CPU_IA32
# include <signal.h>
#elif defined FLAC__CPU_PPC
# if !defined FLAC__NO_ASM
# if defined FLAC__SYS_DARWIN
# include <sys/sysctl.h>
# include <mach/mach.h>
# include <mach/mach_host.h>
# include <mach/host_info.h>
# include <mach/machine.h>
# ifndef CPU_SUBTYPE_POWERPC_970
# define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
# endif
# else /* FLAC__SYS_DARWIN */
# include <signal.h>
# include <setjmp.h>
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;
static void sigill_handler (int sig)
static void disable_sse(FLAC__CPUInfo *info)
{
if (!canjump) {
signal (sig, SIG_DFL);
raise (sig);
}
canjump = 0;
siglongjmp (jmpbuf, 1);
info->ia32.sse = false;
info->ia32.sse2 = false;
info->ia32.sse3 = false;
info->ia32.ssse3 = false;
info->ia32.sse41 = false;
info->ia32.sse42 = false;
}
static void disable_avx(FLAC__CPUInfo *info)
{
info->ia32.avx = false;
info->ia32.avx2 = false;
info->ia32.fma = false;
}
# endif /* FLAC__SYS_DARWIN */
# endif /* FLAC__NO_ASM */
#endif /* FLAC__CPU_PPC */
#elif defined FLAC__CPU_X86_64
static void disable_avx(FLAC__CPUInfo *info)
{
info->x86.avx = false;
info->x86.avx2 = false;
info->x86.fma = false;
}
#endif
#if defined (__NetBSD__) || defined(__OpenBSD__)
#include <sys/param.h>
@@ -87,25 +87,34 @@ static void sigill_handler (int sig)
/* how to get sysctlbyname()? */
#endif
#ifdef FLAC__CPU_IA32
/* these are flags in EDX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
#endif
/* these are flags in ECX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
/* these are flags in EDX of CPUID AX=80000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
#if defined FLAC__AVX_SUPPORTED
/* these are flags in ECX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
/* these are flags in EBX of CPUID AX=00000007 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
#endif
/*
* Extra stuff needed for detection of OS support for SSE on IA-32
*/
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS
# if defined(__linux__)
/*
* If the OS doesn't support SSE, we will get here with a SIGILL. We
@@ -120,35 +129,14 @@ static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
* 6 bytes extra in case our estimate is wrong
* 12 bytes puts us in the NOP "landing zone"
*/
# undef USE_OBSOLETE_SIGCONTEXT_FLAVOR /* #define this to use the older signal handler method */
# ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
static void sigill_handler_sse_os(int signal, struct sigcontext sc)
{
(void)signal;
sc.eip += 3 + 3 + 6;
}
# else
# include <sys/ucontext.h>
static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
{
(void)signal, (void)si;
((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6;
}
# endif
# elif defined(_MSC_VER)
# include <windows.h>
# define USE_TRY_CATCH_FLAVOR /* sigill_handler flavor resulted in several crash reports on win32 */
# ifdef USE_TRY_CATCH_FLAVOR
# else
LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep)
{
if(ep->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) {
ep->ContextRecord->Eip += 3 + 3 + 6;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
# endif
# endif
#endif
@@ -159,261 +147,344 @@ void FLAC__cpu_info(FLAC__CPUInfo *info)
* IA32-specific
*/
#ifdef FLAC__CPU_IA32
FLAC__bool ia32_fxsr = false;
FLAC__bool ia32_osxsave = false;
(void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */
memset(info, 0, sizeof(*info));
info->type = FLAC__CPUINFO_TYPE_IA32;
#if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN)
info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
info->data.ia32.cpuid = FLAC__cpu_have_cpuid_asm_ia32()? true : false;
info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since it came after */
info->data.ia32.cmov = false;
info->data.ia32.mmx = false;
info->data.ia32.fxsr = false;
info->data.ia32.sse = false;
info->data.ia32.sse2 = false;
info->data.ia32.sse3 = false;
info->data.ia32.ssse3 = false;
info->data.ia32._3dnow = false;
info->data.ia32.ext3dnow = false;
info->data.ia32.extmmx = false;
if(info->data.ia32.cpuid) {
/* http://www.sandpile.org/ia32/cpuid.htm */
FLAC__uint32 flags_edx, flags_ecx;
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
info->data.ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
info->data.ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
info->data.ia32.fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
info->data.ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
info->data.ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
info->data.ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->data.ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
#ifdef FLAC__USE_3DNOW
flags_edx = FLAC__cpu_info_extended_amd_asm_ia32();
info->data.ia32._3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW )? true : false;
info->data.ia32.ext3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false;
info->data.ia32.extmmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX )? true : false;
#ifdef FLAC__HAS_X86INTRIN
if(!FLAC__cpu_have_cpuid_x86())
return;
#else
if(!FLAC__cpu_have_cpuid_asm_ia32())
return;
#endif
{
/* http://www.sandpile.org/x86/cpuid.htm */
#ifdef FLAC__HAS_X86INTRIN
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
#else
info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false;
FLAC__uint32 flags_ecx, flags_edx;
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
#endif
info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
#if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
#endif
}
#ifdef DEBUG
fprintf(stderr, "CPU info (IA-32):\n");
fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n');
fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n');
fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n');
fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n');
fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n');
fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n');
fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n');
fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n');
fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n');
fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n');
fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n');
fprintf(stderr, "CPU info (IA-32):\n");
fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
# if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
# endif
#endif
/*
* now have to check for OS support of SSE/SSE2
*/
if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia32.sse2) {
/*
* now have to check for OS support of SSE instructions
*/
if(info->ia32.sse) {
#if defined FLAC__NO_SSE_OS
/* assume user knows better than us; turn it off */
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
/* assume user knows better than us; turn it off */
disable_sse(info);
#elif defined FLAC__SSE_OS
/* assume user knows better than us; leave as detected above */
/* assume user knows better than us; leave as detected above */
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
int sse = 0;
size_t len;
/* at least one of these must work: */
len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
int sse = 0;
size_t len;
/* at least one of these must work: */
len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
if(!sse)
disable_sse(info);
#elif defined(__NetBSD__) || defined (__OpenBSD__)
# if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
size_t len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
else { /* double-check SSE2 */
mib[1] = CPU_SSE2;
len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
size_t len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
disable_sse(info);
else { /* double-check SSE2 */
mib[1] = CPU_SSE2;
len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) {
disable_sse(info);
info->ia32.sse = true;
}
}
# else
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
disable_sse(info);
# endif
#elif defined(__linux__)
int sse = 0;
struct sigaction sigill_save;
#ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal(SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR)
#else
struct sigaction sigill_sse;
sigill_sse.sa_sigaction = sigill_handler_sse_os;
__sigemptyset(&sigill_sse.sa_mask);
sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */
if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
#endif
{
/* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
/* see sigill_handler_sse_os() for an explanation of the following: */
asm volatile (
"xorl %0,%0\n\t" /* for some reason, still need to do this to clear 'sse' var */
"xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
"incl %0\n\t" /* SIGILL handler will jump over this */
/* landing zone */
"nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
"nop\n\t"
"nop" /* SIGILL jump lands here if "inc" is 1 byte */
: "=r"(sse)
: "r"(sse)
);
sigaction(SIGILL, &sigill_save, NULL);
}
int sse = 0;
struct sigaction sigill_save;
struct sigaction sigill_sse;
sigill_sse.sa_sigaction = sigill_handler_sse_os;
__sigemptyset(&sigill_sse.sa_mask);
sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */
if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
{
/* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
/* see sigill_handler_sse_os() for an explanation of the following: */
asm volatile (
"xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
"incl %0\n\t" /* SIGILL handler will jump over this */
/* landing zone */
"nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
"nop\n\t"
"nop" /* SIGILL jump lands here if "inc" is 1 byte */
: "=r"(sse)
: "0"(sse)
);
if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
sigaction(SIGILL, &sigill_save, NULL);
}
if(!sse)
disable_sse(info);
#elif defined(_MSC_VER)
# ifdef USE_TRY_CATCH_FLAVOR
_try {
__asm {
# if _MSC_VER <= 1200
/* VC6 assembler doesn't know SSE, have to emit bytecode instead */
_emit 0x0F
_emit 0x57
_emit 0xC0
# else
xorps xmm0,xmm0
# endif
}
}
_except(EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
}
# else
int sse = 0;
LPTOP_LEVEL_EXCEPTION_FILTER save = SetUnhandledExceptionFilter(sigill_handler_sse_os);
/* see GCC version above for explanation */
/* http://msdn2.microsoft.com/en-us/library/4ks26t93.aspx */
/* http://www.codeproject.com/cpp/gccasm.asp */
/* http://www.hick.org/~mmiller/msvc_inline_asm.html */
__try {
__asm {
# if _MSC_VER <= 1200
/* VC6 assembler doesn't know SSE, have to emit bytecode instead */
_emit 0x0F
_emit 0x57
_emit 0xC0
# else
xorps xmm0,xmm0
# endif
inc sse
nop
nop
nop
nop
nop
nop
nop
nop
nop
}
SetUnhandledExceptionFilter(save);
if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
# endif
}
__except(EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
disable_sse(info);
}
#elif defined(__GNUC__) /* MinGW goes here */
int sse = 0;
/* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */
/* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */
if (ia32_fxsr) {
struct {
FLAC__uint32 buff[128];
} __attribute__((aligned(16))) fxsr;
FLAC__uint32 old_val, new_val;
asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr));
old_val = fxsr.buff[50];
fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */
fxsr.buff[50] = old_val; /* restore old value in the buffer */
asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */
new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */
fxsr.buff[50] = old_val; /* again restore old value in the buffer */
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */
if ((old_val^new_val) == 0x0013c0de)
sse = 1;
}
if(!sse)
disable_sse(info);
#else
/* no way to test, disable to be safe */
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
/* no way to test, disable to be safe */
disable_sse(info);
#endif
#ifdef DEBUG
fprintf(stderr, " SSE OS sup . %c\n", info->data.ia32.sse ? 'Y' : 'n');
fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n');
#endif
}
else /* info->ia32.sse == false */
disable_sse(info);
}
/*
* now have to check for OS support of AVX instructions
*/
if(info->ia32.avx && ia32_osxsave) {
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
if ((ecr & 0x6) != 0x6)
disable_avx(info);
#ifdef DEBUG
fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
#endif
}
else /* no OS AVX support*/
disable_avx(info);
#else
info->use_asm = false;
#endif
/*
* PPC-specific
* x86-64-specific
*/
#elif defined FLAC__CPU_PPC
info->type = FLAC__CPUINFO_TYPE_PPC;
# if !defined FLAC__NO_ASM
#elif defined FLAC__CPU_X86_64
FLAC__bool x86_osxsave = false;
(void) x86_osxsave; /* to avoid warnings about unused variables */
memset(info, 0, sizeof(*info));
info->type = FLAC__CPUINFO_TYPE_X86_64;
#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
info->use_asm = true;
# ifdef FLAC__USE_ALTIVEC
# if defined FLAC__SYS_DARWIN
{
int val = 0, mib[2] = { CTL_HW, HW_VECTORUNIT };
size_t len = sizeof(val);
info->data.ppc.altivec = !(sysctl(mib, 2, &val, &len, NULL, 0) || !val);
/* http://www.sandpile.org/x86/cpuid.htm */
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
#if defined FLAC__AVX_SUPPORTED
x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
#endif
}
{
host_basic_info_data_t hostInfo;
mach_msg_type_number_t infoCount;
infoCount = HOST_BASIC_INFO_COUNT;
host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
#ifdef DEBUG
fprintf(stderr, "CPU info (x86-64):\n");
fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
# if defined FLAC__AVX_SUPPORTED
fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
# endif
#endif
info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
/*
* now have to check for OS support of AVX instructions
*/
if(info->x86.avx && x86_osxsave) {
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
if ((ecr & 0x6) != 0x6)
disable_avx(info);
#ifdef DEBUG
fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
#endif
}
# else /* FLAC__USE_ALTIVEC && !FLAC__SYS_DARWIN */
{
/* no Darwin, do it the brute-force way */
/* @@@@@@ this is not thread-safe; replace with SSE OS method above or remove */
info->data.ppc.altivec = 0;
info->data.ppc.ppc64 = 0;
else /* no OS AVX support*/
disable_avx(info);
#else
info->use_asm = false;
#endif
signal (SIGILL, sigill_handler);
canjump = 0;
if (!sigsetjmp (jmpbuf, 1)) {
canjump = 1;
/*
* unknown CPU
*/
#else
info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
info->use_asm = false;
#endif
}
asm volatile (
"mtspr 256, %0\n\t"
"vand %%v0, %%v0, %%v0"
:
: "r" (-1)
);
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
info->data.ppc.altivec = 1;
}
canjump = 0;
if (!sigsetjmp (jmpbuf, 1)) {
int x = 0;
canjump = 1;
/* PPC64 hardware implements the cntlzd instruction */
asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) );
#if defined _MSC_VER
#include <intrin.h> /* for __cpuid() and _xgetbv() */
#elif defined __GNUC__ && defined HAVE_CPUID_H
#include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
#endif
info->data.ppc.ppc64 = 1;
}
signal (SIGILL, SIG_DFL); /*@@@@@@ should save and restore old signal */
FLAC__uint32 FLAC__cpu_have_cpuid_x86(void)
{
#ifdef FLAC__CPU_X86_64
return 1;
#else
# if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */
FLAC__uint32 flags1, flags2;
__asm {
pushfd
pushfd
pop eax
mov flags1, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
mov flags2, eax
popfd
}
# endif
# else /* !FLAC__USE_ALTIVEC */
info->data.ppc.altivec = 0;
info->data.ppc.ppc64 = 0;
# endif
if (((flags1^flags2) & 0x200000) != 0)
return 1;
else
return 0;
# elif defined __GNUC__ && defined HAVE_CPUID_H
if (__get_cpuid_max(0, 0) != 0)
return 1;
else
return 0;
# else
info->use_asm = false;
return 0;
# endif
#endif
}
/*
* unknown CPI
*/
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
{
(void) level;
#if defined _MSC_VER || defined __INTEL_COMPILER
int cpuinfo[4];
int ext = level & 0x80000000;
__cpuid(cpuinfo, ext);
if((unsigned)cpuinfo[0] < level) {
*eax = *ebx = *ecx = *edx = 0;
return;
}
#if defined FLAC__AVX_SUPPORTED
__cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
#else
info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
info->use_asm = false;
__cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */
#endif
*eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
#elif defined __GNUC__ && defined HAVE_CPUID_H
FLAC__uint32 ext = level & 0x80000000;
__cpuid(ext, *eax, *ebx, *ecx, *edx);
if (*eax < level) {
*eax = *ebx = *ecx = *edx = 0;
return;
}
__cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
#else
*eax = *ebx = *ecx = *edx = 0;
#endif
}
FLAC__uint32 FLAC__cpu_xgetbv_x86(void)
{
#if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED
return (FLAC__uint32)_xgetbv(0);
#elif defined __GNUC__
FLAC__uint32 lo, hi;
asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0));
return lo;
#else
return 0;
#endif
}
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */

+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


+ 3
- 16
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,21 +30,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
#include <string.h>
#include "../compat.h"
#include "include/private/bitmath.h"
#include "include/private/fixed.h"
#include "../assert.h"
#ifndef M_LN2
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_LN2 0.69314718055994530942
#endif
#ifdef local_abs
#undef local_abs
#endif
@@ -320,20 +316,11 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with MSVC you have to spoon feed it the casting */
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
#else
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
#endif
#else
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0;
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;


+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/float.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


+ 3
- 8
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/format.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -45,12 +45,7 @@
/* VERSION should come from configure */
FLAC_API const char *FLAC__VERSION_STRING = VERSION;
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
/* yet one more hack because of MSVC6: */
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.0 20130526";
#else
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20130526";
#endif
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125";
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 48
- 33
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#define FLAC__PRIVATE__BITMATH_H
#include "../../../ordinals.h"
#include "../../../assert.h"
/* for CHAR_BIT */
#include <limits.h>
@@ -74,16 +75,19 @@ static inline unsigned int FLAC__clz_soft_uint32(unsigned int word)
static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v)
{
/* Never used with input 0 */
FLAC__ASSERT(v > 0);
#if defined(__INTEL_COMPILER)
return _bit_scan_reverse(v) ^ 31U;
#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on
* -march= setting or to a software rutine in exotic machines. */
* -march= setting or to a software routine in exotic machines. */
return __builtin_clz(v);
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
FLAC__uint32 idx;
_BitScanReverse((DWORD*) &idx, v);
return idx ^ 31U;
{
unsigned long idx;
_BitScanReverse(&idx, v);
return idx ^ 31U;
}
#else
return FLAC__clz_soft_uint32(v);
#endif
@@ -99,7 +103,7 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
/* An example of what FLAC__bitmath_ilog2() computes:
*
* ilog2( 0) = undefined
* ilog2( 0) = assertion failure
* ilog2( 1) = 0
* ilog2( 2) = 1
* ilog2( 3) = 1
@@ -122,45 +126,56 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
{
FLAC__ASSERT(v > 0);
#if defined(__INTEL_COMPILER)
return _bit_scan_reverse(v);
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
{
unsigned long idx;
_BitScanReverse(&idx, v);
return idx;
}
#else
return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v);
#endif
}
#ifdef FLAC__INTEGER_ONLY_LIBRARY /*Unused otherwise */
#ifdef FLAC__INTEGER_ONLY_LIBRARY /* Unused otherwise */
static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
{
if (v == 0)
return 0;
FLAC__ASSERT(v > 0);
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v);
/* Sorry, only supported in win64/Itanium.. */
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_WIN64))
FLAC__uint64 idx;
_BitScanReverse64(&idx, v);
return idx ^ 63U;
/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64))
{
unsigned long idx;
_BitScanReverse64(&idx, v);
return idx;
}
#else
/* Brain-damaged compilers will use the fastest possible way that is,
/* Brain-damaged compilers will use the fastest possible way that is,
de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf)
(C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 LGPL (v2 or later).
(C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain).
*/
static const unsigned char DEBRUIJN_IDX64[64]={
0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
};
int ret;
ret= v>0;
v|= v>>1;
v|= v>>2;
v|= v>>4;
v|= v>>8;
v|= v>>16;
v|= v>>32;
v= (v>>1)+1;
ret+=DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F];
return ret;
{
static const unsigned char DEBRUIJN_IDX64[64]={
0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
};
v|= v>>1;
v|= v>>2;
v|= v>>4;
v|= v>>8;
v|= v>>16;
v|= v>>32;
v= (v>>1)+1;
return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F];
}
#endif
}
#endif


+ 2
- 11
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,7 +50,7 @@ typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *b
*/
FLAC__BitReader *FLAC__bitreader_new(void);
void FLAC__bitreader_delete(FLAC__BitReader *br);
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd);
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd);
void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
@@ -82,19 +82,10 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F
FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val);
FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter);
FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
#ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_IA32
# ifdef FLAC__HAS_NASM
FLAC__bool FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
# endif
# endif
#endif
#if 0 /* UNUSED */
FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter);
FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
#endif
FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen);
FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen);
FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br);
#endif

+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 31
- 21
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,49 +41,59 @@
typedef enum {
FLAC__CPUINFO_TYPE_IA32,
FLAC__CPUINFO_TYPE_PPC,
FLAC__CPUINFO_TYPE_X86_64,
FLAC__CPUINFO_TYPE_UNKNOWN
} FLAC__CPUInfo_Type;
#if defined FLAC__CPU_IA32
typedef struct {
FLAC__bool cpuid;
FLAC__bool bswap;
FLAC__bool cmov;
FLAC__bool mmx;
FLAC__bool fxsr;
FLAC__bool sse;
FLAC__bool sse2;
FLAC__bool sse3;
FLAC__bool ssse3;
FLAC__bool _3dnow;
FLAC__bool ext3dnow;
FLAC__bool extmmx;
FLAC__bool sse41;
FLAC__bool sse42;
FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_IA32;
#elif defined FLAC__CPU_X86_64
typedef struct {
FLAC__bool altivec;
FLAC__bool ppc64;
} FLAC__CPUInfo_PPC;
FLAC__bool sse3;
FLAC__bool ssse3;
FLAC__bool sse41;
FLAC__bool sse42;
FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_x86;
#endif
typedef struct {
FLAC__bool use_asm;
FLAC__CPUInfo_Type type;
union {
FLAC__CPUInfo_IA32 ia32;
FLAC__CPUInfo_PPC ppc;
} data;
#if defined FLAC__CPU_IA32
FLAC__CPUInfo_IA32 ia32;
#elif defined FLAC__CPU_X86_64
FLAC__CPUInfo_x86 x86;
#endif
} FLAC__CPUInfo;
void FLAC__cpu_info(FLAC__CPUInfo *info);
#ifndef FLAC__NO_ASM
#ifdef FLAC__CPU_IA32
#ifdef FLAC__HAS_NASM
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
FLAC__uint32 FLAC__cpu_info_extended_amd_asm_ia32(void);
#endif
#endif
# endif
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
FLAC__uint32 FLAC__cpu_have_cpuid_x86(void);
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
FLAC__uint32 FLAC__cpu_xgetbv_x86(void);
# endif
#endif
#endif

+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,7 +51,7 @@ FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len);
*/
extern unsigned const FLAC__crc16_table[256];
#define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]))
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])
/* this alternate may be faster on some systems/compilers */
#if 0
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)


+ 14
- 5
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
#include <config.h>
#endif
#include "cpu.h"
#include "float.h"
#include "../../../format.h"
@@ -54,14 +55,22 @@
*/
#ifndef FLAC__INTEGER_ONLY_LIBRARY
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_IA32
# ifdef FLAC__HAS_NASM
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE2_SUPPORTED
unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
# endif
# ifdef FLAC__SSSE3_SUPPORTED
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
# endif
# endif
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# endif
# endif
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#else
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 37
- 6
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
#include <config.h>
#endif
#include "cpu.h"
#include "float.h"
#include "../../../format.h"
@@ -75,7 +76,15 @@ void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigne
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
# endif
# endif
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE_SUPPORTED
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
# endif
# endif
#endif
@@ -145,6 +154,22 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
# ifdef FLAC__HAS_NASM
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# endif
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE2_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# ifdef FLAC__AVX2_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# endif
#endif
@@ -173,11 +198,17 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
# ifdef FLAC__HAS_NASM
void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif /* FLAC__HAS_NASM */
# elif defined FLAC__CPU_PPC
void FLAC__lpc_restore_signal_asm_ppc_altivec_16(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */
# endif /* FLAC__CPU_IA32 */
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE2_SUPPORTED
void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif
# endif
#endif /* FLAC__NO_ASM */
#ifndef FLAC__INTEGER_ONLY_LIBRARY


+ 7
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h View File

@@ -28,11 +28,17 @@
#include "../../../ordinals.h"
typedef union {
FLAC__byte *p8;
FLAC__int16 *p16;
FLAC__int32 *p32;
} FLAC__multibyte;
typedef struct {
FLAC__uint32 in[16];
FLAC__uint32 buf[4];
FLAC__uint32 bytes[2];
FLAC__byte *internal_buf;
FLAC__multibyte internal_buf;
size_t capacity;
} FLAC__MD5Context;


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 67
- 0
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h View File

@@ -0,0 +1,67 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLAC__PRIVATE__STREAM_ENCODER_H
#define FLAC__PRIVATE__STREAM_ENCODER_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*
* This is used to avoid overflow with unusual signals in 32-bit
* accumulator in the *precompute_partition_info_sums_* functions.
*/
#define FLAC__MAX_EXTRA_RESIDUAL_BPS 4
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "cpu.h"
#include "../../../format.h"
#ifdef FLAC__SSE2_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#ifdef FLAC__SSSE3_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#ifdef FLAC__AVX2_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#endif
#endif

+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 3
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,6 +65,8 @@ void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p);
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 2
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,6 +40,7 @@
typedef struct FLAC__StreamDecoderProtected {
FLAC__StreamDecoderState state;
FLAC__StreamDecoderInitStatus initstate;
unsigned channels;
FLAC__ChannelAssignment channel_assignment;
unsigned bits_per_sample;


+ 8
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,6 +59,8 @@ typedef enum {
FLAC__APODIZATION_RECTANGLE,
FLAC__APODIZATION_TRIANGLE,
FLAC__APODIZATION_TUKEY,
FLAC__APODIZATION_PARTIAL_TUKEY,
FLAC__APODIZATION_PUNCHOUT_TUKEY,
FLAC__APODIZATION_WELCH
} FLAC__ApodizationFunction;
@@ -71,6 +73,11 @@ typedef struct {
struct {
FLAC__real p;
} tukey;
struct {
FLAC__real p;
FLAC__real start;
FLAC__real end;
} multiple_tukey;
} parameters;
} FLAC__ApodizationSpecification;


+ 17
- 13
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -50,11 +50,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef M_LN2
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_LN2 0.69314718055994530942
#endif
#if !defined(HAVE_LROUND)
#if defined(_MSC_VER)
#include <float.h>
@@ -65,7 +60,7 @@
static inline long int lround(double x) {
return (long)(x + copysign (0.5, x));
}
//If this fails, we are in the precence of a mid 90's compiler..move along...
/* If this fails, we are in the presence of a mid 90's compiler, move along... */
#endif
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
@@ -160,7 +155,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o
lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
error[i] = err;
/* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */
/* see SF bug https://sourceforge.net/p/flac/bugs/234/ */
if(err == 0.0) {
*max_order = i+1;
return;
@@ -264,7 +259,12 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
return 0;
}
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
#if defined(_MSC_VER)
// silence MSVC warnings about __restrict modifier
#pragma warning ( disable : 4028 )
#endif
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo;
@@ -524,7 +524,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u
}
#endif
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
unsigned i, j;
@@ -780,7 +780,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo;
@@ -1041,7 +1041,7 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c
}
#endif
void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
unsigned i, j;
@@ -1295,6 +1295,10 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
#endif
#if defined(_MSC_VER)
#pragma warning ( default : 4028 )
#endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)


+ 203
- 106
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c View File

@@ -1,4 +1,4 @@
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -7,6 +7,7 @@
#include "include/private/md5.h"
#include "../alloc.h"
#include "../endswap.h"
/*
* This code implements the MD5 message-digest algorithm.
@@ -223,7 +224,7 @@ void FLAC__MD5Init(FLAC__MD5Context *ctx)
ctx->bytes[0] = 0;
ctx->bytes[1] = 0;
ctx->internal_buf = 0;
ctx->internal_buf.p8= 0;
ctx->capacity = 0;
}
@@ -259,9 +260,9 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
if(0 != ctx->internal_buf) {
free(ctx->internal_buf);
ctx->internal_buf = 0;
if (0 != ctx->internal_buf.p8) {
free(ctx->internal_buf.p8);
ctx->internal_buf.p8= 0;
ctx->capacity = 0;
}
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
@@ -270,58 +271,124 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
/*
* Convert the incoming audio signal to a byte stream
*/
static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
{
FLAC__byte *buf_ = mbuf->p8;
FLAC__int16 *buf16 = mbuf->p16;
FLAC__int32 *buf32 = mbuf->p32;
FLAC__int32 a_word;
unsigned channel, sample;
register FLAC__int32 a_word;
register FLAC__byte *buf_ = buf;
#if WORDS_BIGENDIAN
#else
if(channels == 2 && bytes_per_sample == 2) {
FLAC__int16 *buf1_ = ((FLAC__int16*)buf_) + 1;
memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples);
for(sample = 0; sample < samples; sample++, buf1_+=2)
*buf1_ = (FLAC__int16)signal[1][sample];
}
else if(channels == 1 && bytes_per_sample == 2) {
FLAC__int16 *buf1_ = (FLAC__int16*)buf_;
for(sample = 0; sample < samples; sample++)
*buf1_++ = (FLAC__int16)signal[0][sample];
}
else
#endif
if(bytes_per_sample == 2) {
if(channels == 2) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
a_word = signal[1][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
/* Storage in the output buffer, buf, is little endian. */
#define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
/* First do the most commonly used combinations. */
switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
/* One byte per sample. */
case (BYTES_CHANNEL_SELECTOR (1, 1)):
for (sample = 0; sample < samples; sample++)
*buf_++ = signal[0][sample];
return;
case (BYTES_CHANNEL_SELECTOR (1, 2)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
}
}
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) {
return;
case (BYTES_CHANNEL_SELECTOR (1, 4)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
}
return;
case (BYTES_CHANNEL_SELECTOR (1, 6)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
*buf_++ = signal[4][sample];
*buf_++ = signal[5][sample];
}
return;
case (BYTES_CHANNEL_SELECTOR (1, 8)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
*buf_++ = signal[4][sample];
*buf_++ = signal[5][sample];
*buf_++ = signal[6][sample];
*buf_++ = signal[7][sample];
}
return;
/* Two bytes per sample. */
case (BYTES_CHANNEL_SELECTOR (2, 1)):
for (sample = 0; sample < samples; sample++)
*buf16++ = H2LE_16(signal[0][sample]);
return;
case (BYTES_CHANNEL_SELECTOR (2, 2)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 4)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 6)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
*buf16++ = H2LE_16(signal[4][sample]);
*buf16++ = H2LE_16(signal[5][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 8)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
*buf16++ = H2LE_16(signal[4][sample]);
*buf16++ = H2LE_16(signal[5][sample]);
*buf16++ = H2LE_16(signal[6][sample]);
*buf16++ = H2LE_16(signal[7][sample]);
}
return;
/* Three bytes per sample. */
case (BYTES_CHANNEL_SELECTOR (3, 1)):
for (sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
else {
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
}
}
else if(bytes_per_sample == 3) {
if(channels == 2) {
for(sample = 0; sample < samples; sample++) {
return;
case (BYTES_CHANNEL_SELECTOR (3, 2)):
for (sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
@@ -331,60 +398,90 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
return;
/* Four bytes per sample. */
case (BYTES_CHANNEL_SELECTOR (4, 1)):
for (sample = 0; sample < samples; sample++)
*buf32++ = H2LE_32(signal[0][sample]);
return;
case (BYTES_CHANNEL_SELECTOR (4, 2)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
}
}
else {
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
return;
case (BYTES_CHANNEL_SELECTOR (4, 4)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
}
}
}
else if(bytes_per_sample == 1) {
if(channels == 2) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word;
a_word = signal[1][sample];
*buf_++ = (FLAC__byte)a_word;
return;
case (BYTES_CHANNEL_SELECTOR (4, 6)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
*buf32++ = H2LE_32(signal[4][sample]);
*buf32++ = H2LE_32(signal[5][sample]);
}
}
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word;
return;
case (BYTES_CHANNEL_SELECTOR (4, 8)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
*buf32++ = H2LE_32(signal[4][sample]);
*buf32++ = H2LE_32(signal[5][sample]);
*buf32++ = H2LE_32(signal[6][sample]);
*buf32++ = H2LE_32(signal[7][sample]);
}
}
else {
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
return;
default:
break;
}
/* General version. */
switch (bytes_per_sample) {
case 1:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++)
*buf_++ = signal[channel][sample];
return;
case 2:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++)
*buf16++ = H2LE_16(signal[channel][sample]);
return;
case 3:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
}
}
else { /* bytes_per_sample == 4, maybe optimize more later */
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
return;
case 4:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++)
*buf32++ = H2LE_32(signal[channel][sample]);
return;
default:
break;
}
}
@@ -396,26 +493,26 @@ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const
const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
/* overflow check */
if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
return false;
if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
return false;
if(ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf, bytes_needed);
if(0 == tmp) {
free(ctx->internal_buf);
if(0 == (ctx->internal_buf = (FLAC__byte*) safe_malloc_(bytes_needed)))
if (ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf.p8, bytes_needed);
if (0 == tmp) {
free(ctx->internal_buf.p8);
if (0 == (ctx->internal_buf.p8= (FLAC__byte*) safe_malloc_(bytes_needed)))
return false;
}
else
ctx->internal_buf = tmp;
ctx->internal_buf.p8= tmp;
ctx->capacity = bytes_needed;
}
format_input_(ctx->internal_buf, signal, channels, samples, bytes_per_sample);
format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample);
FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed);
FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed);
return true;
}

+ 8
- 21
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,10 +30,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "include/private/memory.h"
#include "../assert.h"
#include "../alloc.h"
@@ -46,25 +50,8 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
#ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */
x = safe_malloc_add_2op_(bytes, /*+*/31);
#ifdef SIZEOF_VOIDP
#if SIZEOF_VOIDP == 4
/* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
*aligned_address = (void*)(((unsigned)x + 31) & -32);
#elif SIZEOF_VOIDP == 8
*aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
#else
# error Unsupported sizeof(void*)
#endif
#else
/* there's got to be a better way to do this right for all archs */
if(sizeof(void*) == sizeof(unsigned))
*aligned_address = (void*)(((unsigned)x + 31) & -32);
else if(sizeof(void*) == sizeof(FLAC__uint64))
*aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
else
return 0;
#endif
x = safe_malloc_add_2op_(bytes, /*+*/31L);
*aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
#else
x = safe_malloc_(bytes);
*aligned_address = x;


+ 123
- 100
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -70,7 +70,7 @@ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC =
*
***********************************************************************/
static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
/***********************************************************************
*
@@ -86,7 +86,7 @@ static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj);
static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length);
static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
@@ -141,9 +141,6 @@ typedef struct FLAC__StreamDecoderPrivate {
void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
/* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
/* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */
void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
void *client_data;
FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
FLAC__BitReader *input;
@@ -380,7 +377,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
#if FLAC__HAS_OGG
decoder->private_->is_ogg = is_ogg;
if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
return decoder->protected_->state = FLAC__STREAM_DECODER_OGG_ERROR;
return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
#endif
/*
@@ -391,42 +388,44 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal;
decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block;
/* now override with asm where appropriate */
#ifndef FLAC__NO_ASM
if(decoder->private_->cpuinfo.use_asm) {
#ifdef FLAC__CPU_IA32
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
#ifdef FLAC__HAS_NASM
#if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */
if(decoder->private_->cpuinfo.data.ia32.bswap)
decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap;
#endif
if(decoder->private_->cpuinfo.data.ia32.mmx) {
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
if(decoder->private_->cpuinfo.ia32.mmx) {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx;
}
else {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32;
}
#endif
#elif defined FLAC__CPU_PPC
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC);
if(decoder->private_->cpuinfo.data.ppc.altivec) {
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8;
#ifdef FLAC__HAS_X86INTRIN
# if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */
if(decoder->private_->cpuinfo.ia32.sse2) {
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2;
}
# endif
# if defined FLAC__SSE4_1_SUPPORTED
if(decoder->private_->cpuinfo.ia32.sse41) {
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41;
}
# endif
#endif
#elif defined FLAC__CPU_X86_64
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
/* No useful SSE optimizations yet */
#endif
}
#endif
/* from here on, errors are fatal */
if(!FLAC__bitreader_init(decoder->private_->input, decoder->private_->cpuinfo, read_callback_, decoder)) {
if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
}
@@ -528,10 +527,10 @@ static FLAC__StreamDecoderInitStatus init_FILE_internal_(
FLAC__ASSERT(0 != file);
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED);
return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
if(0 == write_callback || 0 == error_callback)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS);
return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
/*
* To make sure that our file does not go unclosed after an error, we
@@ -602,10 +601,10 @@ static FLAC__StreamDecoderInitStatus init_file_internal_(
* in FLAC__stream_decoder_init_FILE() before the FILE* is assigned.
*/
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED);
return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
if(0 == write_callback || 0 == error_callback)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS);
return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
file = filename? flac_fopen(filename, "rb") : stdin;
@@ -652,7 +651,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
return true;
/* see the comment in FLAC__seekable_stream_decoder_reset() as to why we
/* see the comment in FLAC__stream_decoder_reset() as to why we
* always call FLAC__MD5Final()
*/
FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
@@ -1316,9 +1315,6 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
memset(tmp, 0, sizeof(FLAC__int32)*4);
decoder->private_->output[i] = tmp + 4;
/* WATCHOUT:
* minimum of quadword alignment for PPC vector optimizations is REQUIRED:
*/
if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
@@ -1368,6 +1364,10 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
id_ = 0;
continue;
}
if(id_ >= 3)
return false;
if(x == ID3V2_TAG_[id_]) {
id_++;
i = 0;
@@ -1446,6 +1446,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
unsigned real_length = length;
FLAC__StreamMetadata block;
memset(&block, 0, sizeof(block));
block.is_last = is_last;
block.type = (FLAC__MetadataType)type;
block.length = length;
@@ -1470,36 +1471,37 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
return false; /* read_callback_ sets the state for us */
}
else {
FLAC__bool ok = true;
switch(type) {
case FLAC__METADATA_TYPE_PADDING:
/* skip the padding bytes */
if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
return false; /* read_callback_ sets the state for us */
ok = false; /* read_callback_ sets the state for us */
break;
case FLAC__METADATA_TYPE_APPLICATION:
/* remember, we read the ID already */
if(real_length > 0) {
if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
ok = false;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length))
return false; /* read_callback_ sets the state for us */
else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length))
ok = false; /* read_callback_ sets the state for us */
}
else
block.data.application.data = 0;
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment))
return false;
if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length))
ok = false;
break;
case FLAC__METADATA_TYPE_CUESHEET:
if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
return false;
ok = false;
break;
case FLAC__METADATA_TYPE_PICTURE:
if(!read_metadata_picture_(decoder, &block.data.picture))
return false;
ok = false;
break;
case FLAC__METADATA_TYPE_STREAMINFO:
case FLAC__METADATA_TYPE_SEEKTABLE:
@@ -1509,16 +1511,16 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
if(real_length > 0) {
if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
ok = false;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length))
return false; /* read_callback_ sets the state for us */
else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length))
ok = false; /* read_callback_ sets the state for us */
}
else
block.data.unknown.data = 0;
break;
}
if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback)
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
/* now we have to free any malloc()ed data in the block */
@@ -1563,6 +1565,9 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
free(block.data.unknown.data);
break;
}
if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */
return false;
}
}
@@ -1689,58 +1694,88 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_
return true;
}
FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj)
FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length)
{
FLAC__uint32 i;
FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
/* read vendor string */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */
if(obj->vendor_string.length > 0) {
if(0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
if (length >= 8) {
length -= 8; /* vendor string length + num comments entries alone take 8 bytes */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0';
}
else
obj->vendor_string.entry = 0;
if (obj->vendor_string.length > 0) {
if (length < obj->vendor_string.length) {
obj->vendor_string.length = 0;
obj->vendor_string.entry = 0;
goto skip;
}
else
length -= obj->vendor_string.length;
if (0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0';
}
else
obj->vendor_string.entry = 0;
/* read num comments */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
return false; /* read_callback_ sets the state for us */
/* read num comments */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
return false; /* read_callback_ sets the state for us */
/* read comments */
if(obj->num_comments > 0) {
if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
for(i = 0; i < obj->num_comments; i++) {
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
if(obj->comments[i].length > 0) {
if(0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
/* read comments */
if (obj->num_comments > 0) {
if (0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
for (i = 0; i < obj->num_comments; i++) {
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if (length < 4) {
obj->num_comments = i;
goto skip;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
else
length -= 4;
if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
obj->comments[i].entry[obj->comments[i].length] = '\0';
if (obj->comments[i].length > 0) {
if (length < obj->comments[i].length) {
obj->comments[i].length = 0;
obj->comments[i].entry = 0;
obj->num_comments = i;
goto skip;
}
else
length -= obj->comments[i].length;
if (0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
obj->comments[i].entry[obj->comments[i].length] = '\0';
}
else
obj->comments[i].entry = 0;
}
else
obj->comments[i].entry = 0;
}
else
obj->comments = 0;
}
else {
obj->comments = 0;
skip:
if (length > 0) {
/* This will only happen on files with invalid data in comments */
if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
return false; /* read_callback_ sets the state for us */
}
return true;
@@ -2655,12 +2690,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un
if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) )
*/
if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
if(bps <= 16 && subframe->qlp_coeff_precision <= 16) {
if(order <= 8)
decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
else
decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
}
if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
else
decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
else
@@ -2708,14 +2739,16 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
if(decoder->private_->frame.header.blocksize < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true;
/* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
return false;
}
}
else {
if(partition_samples < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true;
/* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
return false;
}
}
@@ -2732,7 +2765,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
if(rice_parameter < pesc) {
partitioned_rice_contents->raw_bits[partition] = 0;
u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
return false; /* read_callback_ sets the state for us */
sample += u;
}
@@ -3074,12 +3107,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
return false;
}
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with VC++ you have to spoon feed it the casting */
pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame;
#else
pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
#endif
#else
/* a little less accurate: */
if(upper_bound - lower_bound < 0xffffffff)
@@ -3203,12 +3231,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint
}
else {
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with MSVC you have to spoon feed it the casting */
pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
#else
pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
#endif
#else
/* a little less accurate: */
if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))


+ 245
- 54
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -55,10 +55,10 @@
#include "include/private/ogg_helper.h"
#include "include/private/ogg_mapping.h"
#endif
#include "include/private/stream_encoder.h"
#include "include/private/stream_encoder_framing.h"
#include "include/private/window.h"
#include "../alloc.h"
#include "../compat.h"
/* Exact Rice codeword length calculation is off by default. The simple
@@ -103,16 +103,18 @@ static struct CompressionLevels {
unsigned min_residual_partition_order;
unsigned max_residual_partition_order;
unsigned rice_parameter_search_dist;
const char *apodization;
} compression_levels_[] = {
{ false, false, 0, 0, false, false, false, 0, 3, 0 },
{ true , true , 0, 0, false, false, false, 0, 3, 0 },
{ true , false, 0, 0, false, false, false, 0, 3, 0 },
{ false, false, 6, 0, false, false, false, 0, 4, 0 },
{ true , true , 8, 0, false, false, false, 0, 4, 0 },
{ true , false, 8, 0, false, false, false, 0, 5, 0 },
{ true , false, 8, 0, false, false, false, 0, 6, 0 },
{ true , false, 8, 0, false, false, true , 0, 6, 0 },
{ true , false, 12, 0, false, false, true , 0, 6, 0 }
{ false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" }
/* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */
};
@@ -342,10 +344,13 @@ typedef struct FLAC__StreamEncoderPrivate {
unsigned current_frame_number;
FLAC__MD5Context md5context;
FLAC__CPUInfo cpuinfo;
void (*local_precompute_partition_info_sums)(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#else
unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY
void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
@@ -873,7 +878,9 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
#ifndef FLAC__INTEGER_ONLY_LIBRARY
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
#endif
encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_;
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide;
#ifndef FLAC__INTEGER_ONLY_LIBRARY
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide;
@@ -886,21 +893,23 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
# ifdef FLAC__CPU_IA32
FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
# ifdef FLAC__HAS_NASM
if(encoder->private_->cpuinfo.data.ia32.sse) {
if(encoder->private_->cpuinfo.ia32.sse) {
if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16;
else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
}
else if(encoder->private_->cpuinfo.data.ia32._3dnow)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow;
else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
if(encoder->private_->cpuinfo.data.ia32.mmx) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
if(encoder->private_->cpuinfo.ia32.mmx) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx;
}
@@ -908,16 +917,137 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
}
if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov)
if(encoder->private_->cpuinfo.ia32.mmx && encoder->private_->cpuinfo.ia32.cmov)
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
# endif /* FLAC__HAS_NASM */
# endif /* FLAC__CPU_IA32 */
# ifdef FLAC__HAS_X86INTRIN
# if defined FLAC__SSE_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse) {
if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16;
else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
}
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse41) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41;
}
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.avx2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
if (encoder->private_->cpuinfo.ia32.sse2) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2;
}
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if (encoder->private_->cpuinfo.ia32.ssse3) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3;
}
# endif
# endif /* FLAC__HAS_X86INTRIN */
# elif defined FLAC__CPU_X86_64
FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
# ifdef FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE_SUPPORTED
if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16;
# endif
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
if(encoder->private_->cpuinfo.x86.sse41) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41;
}
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.x86.avx2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if (encoder->private_->cpuinfo.x86.ssse3) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3;
}
# endif
# endif /* FLAC__HAS_X86INTRIN */
# endif /* FLAC__CPU_... */
}
# endif /* !FLAC__NO_ASM */
#endif /* !FLAC__INTEGER_ONLY_LIBRARY */
#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
if(encoder->private_->cpuinfo.use_asm) {
# if defined FLAC__CPU_IA32
# ifdef FLAC__SSE2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if(encoder->private_->cpuinfo.ia32.ssse3)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3;
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.avx2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2;
# endif
# elif defined FLAC__CPU_X86_64
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if(encoder->private_->cpuinfo.x86.ssse3)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3;
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.x86.avx2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2;
# endif
# endif /* FLAC__CPU_... */
}
#endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */
/* finally override based on wide-ness if necessary */
if(encoder->private_->use_wide_by_block) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide;
encoder->private_->local_fixed_compute_best_predictor = encoder->private_->local_fixed_compute_best_predictor_wide;
}
/* set state to OK; from here on, errors are fatal and we'll override the state then */
@@ -1152,7 +1282,7 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_(
FLAC__StreamEncoder *encoder,
FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback,
void * /*client_data*/,
void *client_data,
FLAC__bool is_ogg
)
{
@@ -1178,6 +1308,13 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_(
if(file == stdout)
file = get_binary_stdout_(); /* just to be safe */
#ifdef _WIN32
/*
* Windows can suffer quite badly from disk fragmentation. This can be
* reduced significantly by setting the output buffer size to be 10MB.
*/
setvbuf(file, NULL, _IOFBF, 10*1024*1024);
#endif
encoder->private_->file = file;
encoder->private_->progress_callback = progress_callback;
@@ -1447,11 +1584,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncod
ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo);
ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#if 0
/* was: */
#if 1
ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization);
/* but it's too hard to specify the string in a locale-specific way */
#else
/* equivalent to -A tukey(0.5) */
encoder->protected_->num_apodizations = 1;
encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
@@ -1555,6 +1691,48 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
}
}
else if(n>15 && 0 == strncmp("partial_tukey(" , specification, 14)) {
FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0);
const char *si_1 = strchr(specification, '/');
FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f;
FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f;
const char *si_2 = strchr((si_1?(si_1+1):specification), '/');
FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f;
if (tukey_parts <= 1) {
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
}else if (encoder->protected_->num_apodizations + tukey_parts < 32){
FLAC__int32 m;
for(m = 0; m < tukey_parts; m++){
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PARTIAL_TUKEY;
}
}
}
else if(n>16 && 0 == strncmp("punchout_tukey(" , specification, 15)) {
FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0);
const char *si_1 = strchr(specification, '/');
FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f;
FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f;
const char *si_2 = strchr((si_1?(si_1+1):specification), '/');
FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f;
if (tukey_parts <= 1) {
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
}else if (encoder->protected_->num_apodizations + tukey_parts < 32){
FLAC__int32 m;
for(m = 0; m < tukey_parts; m++){
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PUNCHOUT_TUKEY;
}
}
}
else if(n==5 && 0 == strncmp("welch" , specification, n))
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
if (encoder->protected_->num_apodizations == 32)
@@ -2236,8 +2414,8 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
ok = true;
/* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx()
* requires that the input arrays (in our case the integer signals)
/* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2()
* require that the input arrays (in our case the integer signals)
* have a buffer of up to 3 zeroes in front (at negative indices) for
* alignment purposes; we use 4 in front to keep the data well-aligned.
*/
@@ -2334,6 +2512,12 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
case FLAC__APODIZATION_TUKEY:
FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
break;
case FLAC__APODIZATION_PARTIAL_TUKEY:
FLAC__window_partial_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end);
break;
case FLAC__APODIZATION_PUNCHOUT_TUKEY:
FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end);
break;
case FLAC__APODIZATION_WELCH:
FLAC__window_welch(encoder->private_->window[i], new_blocksize);
break;
@@ -3165,7 +3349,7 @@ FLAC__bool process_subframe_(
#endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double lpc_residual_bits_per_sample;
FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */
FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm and x86 intrinsic routines need all the space */
FLAC__double lpc_error[FLAC__MAX_LPC_ORDER];
unsigned min_lpc_order, max_lpc_order, lpc_order;
unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
@@ -3318,9 +3502,9 @@ FLAC__bool process_subframe_(
}
if(encoder->protected_->do_qlp_coeff_prec_search) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
/* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */
if(subframe_bps <= 17) {
max_qlp_coeff_precision = flac_min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION);
/* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
if(subframe_bps <= 16) {
max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION);
max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision);
}
else
@@ -3556,7 +3740,7 @@ unsigned evaluate_lpc_subframe_(
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
)
{
FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /* WATCHOUT: the size is important; some x86 intrinsic routines need more than lpc order elements */
unsigned i, residual_bits, estimate;
int quantization, ret;
const unsigned residual_samples = blocksize - order;
@@ -3671,7 +3855,7 @@ unsigned find_best_partition_order_(
max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order);
min_partition_order = flac_min(min_partition_order, max_partition_order);
precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps);
private_->local_precompute_partition_info_sums(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps);
if(do_escape_coding)
precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order);
@@ -3743,17 +3927,6 @@ unsigned find_best_partition_order_(
return best_residual_bits;
}
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
extern void precompute_partition_info_sums_32bit_asm_ia32_(
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
unsigned blocksize,
unsigned predictor_order,
unsigned min_partition_order,
unsigned max_partition_order
);
#endif
void precompute_partition_info_sums_(
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
@@ -3769,21 +3942,12 @@ void precompute_partition_info_sums_(
FLAC__ASSERT(default_partition_samples > predictor_order);
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
/* slightly pessimistic but still catches all common cases */
/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
precompute_partition_info_sums_32bit_asm_ia32_(residual, abs_residual_partition_sums, residual_samples + predictor_order, predictor_order, min_partition_order, max_partition_order);
return;
}
#endif
/* first do max_partition_order */
{
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
/* slightly pessimistic but still catches all common cases */
/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
/* WATCHOUT: "+ bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum
* assumed size of the average residual magnitude */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
FLAC__uint32 abs_residual_partition_sum;
for(partition = residual_sample = 0; partition < partitions; partition++) {
@@ -4027,8 +4191,35 @@ FLAC__bool set_partitioned_rice_(
* in the partition, so the actual mean is
* mean/partition_samples
*/
#if 0 /* old simple code */
for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
;
#else
#if defined FLAC__CPU_X86_64 /* and other 64-bit arch, too */
if(mean <= 0x80000000/512) { /* 512: more or less optimal for both 16- and 24-bit input */
#else
if(mean <= 0x80000000/8) { /* 32-bit arch: use 32-bit math if possible */
#endif
FLAC__uint32 k2, mean2 = (FLAC__uint32) mean;
rice_parameter = 0; k2 = partition_samples;
while(k2*8 < mean2) { /* requires: mean <= (2^31)/8 */
rice_parameter += 4; k2 <<= 4; /* tuned for 16-bit input */
}
while(k2 < mean2) { /* requires: mean <= 2^31 */
rice_parameter++; k2 <<= 1;
}
}
else {
rice_parameter = 0; k = partition_samples;
if(mean <= FLAC__U64L(0x8000000000000000)/128) /* usually mean is _much_ smaller than this value */
while(k*128 < mean) { /* requires: mean <= (2^63)/128 */
rice_parameter += 8; k <<= 8; /* tuned for 24-bit input */
}
while(k < mean) { /* requires: mean <= 2^63 */
rice_parameter++; k <<= 1;
}
}
#endif
if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);


+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


+ 68
- 13
libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -41,11 +41,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef M_PI
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_PI 3.14159265358979323846
#endif
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
{
@@ -62,7 +57,7 @@ void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
for (n = 0; n <= L/2-1; n++)
window[n] = 2.0f * n / (float)N;
for (; n <= N; n++)
window[n] = 2.0f - 2.0f * (N-n) / (float)N;
window[n] = 2.0f - 2.0f * n / (float)N;
}
}
@@ -72,7 +67,7 @@ void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
FLAC__int32 n;
for (n = 0; n < L; n++)
window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N+0.5f) + 0.38f * cos(2.0f * M_PI * ((float)n/(float)N+0.5f)));
window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N)));
}
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
@@ -177,16 +172,16 @@ void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
FLAC__int32 n;
if (L & 1) {
for (n = 1; n <= L+1/2; n++)
for (n = 1; n <= (L+1)/2; n++)
window[n-1] = 2.0f * n / ((float)L + 1.0f);
for (; n <= L; n++)
window[n-1] = - (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
}
else {
for (n = 1; n <= L/2; n++)
window[n-1] = 2.0f * n / (float)L;
window[n-1] = 2.0f * n / ((float)L + 1.0f);
for (; n <= L; n++)
window[n-1] = ((float)(2 * (L - n)) + 1.0f) / (float)L;
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
}
}
@@ -211,6 +206,66 @@ void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__rea
}
}
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
{
const FLAC__int32 start_n = (FLAC__int32)(start * L);
const FLAC__int32 end_n = (FLAC__int32)(end * L);
const FLAC__int32 N = end_n - start_n;
FLAC__int32 Np, n, i;
if (p <= 0.0f)
FLAC__window_partial_tukey(window, L, 0.05f, start, end);
else if (p >= 1.0f)
FLAC__window_partial_tukey(window, L, 0.95f, start, end);
else {
Np = (FLAC__int32)(p / 2.0f * N);
for (n = 0; n < start_n && n < L; n++)
window[n] = 0.0f;
for (i = 1; n < (start_n+Np) && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
for (; n < (end_n-Np) && n < L; n++)
window[n] = 1.0f;
for (i = Np; n < end_n && n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
for (; n < L; n++)
window[n] = 0.0f;
}
}
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
{
const FLAC__int32 start_n = (FLAC__int32)(start * L);
const FLAC__int32 end_n = (FLAC__int32)(end * L);
FLAC__int32 Ns, Ne, n, i;
if (p <= 0.0f)
FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
else if (p >= 1.0f)
FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
else {
Ns = (FLAC__int32)(p / 2.0f * start_n);
Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
for (n = 0, i = 1; n < Ns && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
for (; n < start_n-Ns && n < L; n++)
window[n] = 1.0f;
for (i = Ns; n < start_n && n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
for (; n < end_n && n < L; n++)
window[n] = 0.0f;
for (i = 1; n < end_n+Ne && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
for (; n < L - (Ne) && n < L; n++)
window[n] = 1.0f;
for (i = Ne; n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
}
}
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
{
const FLAC__int32 N = L - 1;


+ 2
- 2
libs/juce/source/modules/juce_audio_formats/codecs/flac/metadata.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -500,7 +500,7 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const
* \retval unsigned
* The length of the metadata block at the current iterator position.
* The is same length as that in the
* <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>,
* <a href="http://xiph.org/flac/format.html#metadata_block_header">metadata block header</a>,
* i.e. the length of the metadata body that follows the header.
*/
FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/ordinals.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/flac/stream_decoder.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions


+ 45
- 24
libs/juce/source/modules/juce_audio_formats/codecs/flac/stream_encoder.h View File

@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -830,28 +830,28 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en
* The actual values set for each level are:
* <table>
* <tr>
* <td><b>level</b><td>
* <td>do mid-side stereo<td>
* <td>loose mid-side stereo<td>
* <td>apodization<td>
* <td>max lpc order<td>
* <td>qlp coeff precision<td>
* <td>qlp coeff prec search<td>
* <td>escape coding<td>
* <td>exhaustive model search<td>
* <td>min residual partition order<td>
* <td>max residual partition order<td>
* <td>rice parameter search dist<td>
* <td><b>level</b></td>
* <td>do mid-side stereo</td>
* <td>loose mid-side stereo</td>
* <td>apodization</td>
* <td>max lpc order</td>
* <td>qlp coeff precision</td>
* <td>qlp coeff prec search</td>
* <td>escape coding</td>
* <td>exhaustive model search</td>
* <td>min residual partition order</td>
* <td>max residual partition order</td>
* <td>rice parameter search dist</td>
* </tr>
* <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
* <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
* <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
* <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
* <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
* <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr>
* <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr>
* <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
* <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
* <tr> <td><b>0</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>1</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>2</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>3</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>6</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>4</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>5</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>5</td> <td>0</td> </tr>
* <tr> <td><b>6</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>7</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>8</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2);punchout_tukey(3)</td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* </table>
*
* \default \c 5
@@ -920,7 +920,8 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* The available functions are \c bartlett, \c bartlett_hann,
* \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
* \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall,
* \c rectangle, \c triangle, \c tukey(P), \c welch.
* \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]),
* \c punchout_tukey(n[/ov[/P]]), \c welch.
*
* For \c gauss(STDDEV), STDDEV specifies the standard deviation
* (0<STDDEV<=0.5).
@@ -929,6 +930,24 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
* corresponds to \c hann.
*
* Specifying \c partial_tukey or \c punchout_tukey works a little
* different. These do not specify a single apodization function, but
* a series of them with some overlap. partial_tukey specifies a series
* of small windows (all treated separately) while punchout_tukey
* specifies a series of windows that have a hole in them. In this way,
* the predictor is constructed with only a part of the block, which
* helps in case a block consists of dissimilar parts.
*
* The three parameters that can be specified for the functions are
* n, ov and P. n is the number of functions to add, ov is the overlap
* of the windows in case of partial_tukey and the overlap in the gaps
* in case of punchout_tukey. P is the fraction of the window that is
* tapered, like with a regular tukey window. The function can be
* specified with only a number, a number and an overlap, or a number
* an overlap and a P, for example, partial_tukey(3), partial_tukey(3/0.3)
* and partial_tukey(3/0.3/0.5) are all valid. ov should be smaller than 1
* and can be negative.
*
* Example specifications are \c "blackman" or
* \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
*
@@ -941,7 +960,9 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* results in the smallest compressed subframe.
*
* Note that each function specified causes the encoder to occupy a
* floating point array in which to store the window.
* floating point array in which to store the window. Also note that the
* values of P, STDDEV and ov are locale-specific, so if the comma
* separator specified by the locale is a comma, a comma should be used.
*
* \default \c "tukey(0.5)"
* \param encoder An encoder instance to set.


+ 69
- 0
libs/juce/source/modules/juce_audio_formats/codecs/flac/win_utf8_io.h View File

@@ -0,0 +1,69 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2013-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _WIN32
#ifndef flac__win_utf8_io_h
#define flac__win_utf8_io_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <windows.h>
int get_utf8_argv(int *argc, char ***argv);
int printf_utf8(const char *format, ...);
int fprintf_utf8(FILE *stream, const char *format, ...);
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr);
FILE *fopen_utf8(const char *filename, const char *mode);
int stat_utf8(const char *path, struct stat *buffer);
int _stat64_utf8(const char *path, struct __stat64 *buffer);
int chmod_utf8(const char *filename, int pmode);
int utime_utf8(const char *filename, struct utimbuf *times);
int unlink_utf8(const char *filename);
int rename_utf8(const char *oldname, const char *newname);
size_t strlen_utf8(const char *str);
int win_get_console_width(void);
int print_console(FILE *stream, const wchar_t *text, size_t len);
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
#endif

+ 118
- 56
libs/juce/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp View File

@@ -193,47 +193,72 @@ namespace AiffFileHelpers
#endif
//==============================================================================
static String readCATEChunk (InputStream& input, const uint32 length)
namespace CATEChunk
{
MemoryBlock mb;
input.skipNextBytes (4);
input.readIntoMemoryBlock (mb, (ssize_t) length - 4);
static const char* appleGenres[] =
{
"Rock/Blues",
"Electronic/Dance",
"Jazz",
"Urban",
"World/Ethnic",
"Cinematic/New Age",
"Orchestral",
"Country/Folk",
"Experimental",
"Other Genre",
nullptr
};
static bool isValidTag (const char* d) noexcept
{
return CharacterFunctions::isLetterOrDigit (d[0]) && CharacterFunctions::isUpperCase (d[0])
&& CharacterFunctions::isLetterOrDigit (d[1]) && CharacterFunctions::isLowerCase (d[1])
&& CharacterFunctions::isLetterOrDigit (d[2]) && CharacterFunctions::isLowerCase (d[2]);
}
const StringArray genres (appleGenres);
StringArray tagsArray;
static bool isAppleGenre (const String& tag) noexcept
{
static const char* appleGenres[] =
{
"Rock/Blues",
"Electronic/Dance",
"Jazz",
"Urban",
"World/Ethnic",
"Cinematic/New Age",
"Orchestral",
"Country/Folk",
"Experimental",
"Other Genre"
};
for (int i = 0; i < numElementsInArray (appleGenres); ++i)
if (tag == appleGenres[i])
return true;
int bytesLeft = (int) mb.getSize();
const char* data = static_cast<const char*> (mb.getData());
return false;
}
while (bytesLeft > 0)
static String read (InputStream& input, const uint32 length)
{
const String tag (CharPointer_UTF8 (data),
CharPointer_UTF8 (data + bytesLeft));
MemoryBlock mb;
input.skipNextBytes (4);
input.readIntoMemoryBlock (mb, (ssize_t) length - 4);
if (tag.isNotEmpty())
tagsArray.add (data);
StringArray tagsArray;
const int numBytesInTag = genres.contains (tag) ? 118 : 50;
data += numBytesInTag;
bytesLeft -= numBytesInTag;
}
const char* data = static_cast<const char*> (mb.getData());
const char* dataEnd = data + mb.getSize();
while (data < dataEnd)
{
bool isGenre = false;
return tagsArray.joinIntoString (";");
if (isValidTag (data))
{
const String tag = String (CharPointer_UTF8 (data), CharPointer_UTF8 (dataEnd));
isGenre = isAppleGenre (tag);
tagsArray.add (tag);
}
data += isGenre ? 118 : 50;
if (data[0] == 0)
{
if (data + 52 < dataEnd && isValidTag (data + 50)) data += 50;
else if (data + 120 < dataEnd && isValidTag (data + 118)) data += 118;
else if (data + 170 < dataEnd && isValidTag (data + 168)) data += 168;
}
}
return tagsArray.joinIntoString (";");
}
}
//==============================================================================
@@ -518,7 +543,7 @@ public:
else if (type == chunkName ("cate"))
{
metadataValues.set (AiffAudioFormat::appleTag,
AiffFileHelpers::readCATEChunk (*input, length));;
AiffFileHelpers::CATEChunk::read (*input, length));
}
else if ((hasGotVer && hasGotData && hasGotType)
|| chunkEnd < input->getPosition()
@@ -821,12 +846,54 @@ public:
return true;
}
void readMaxLevels (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1)
void getSample (int64 sample, float* result) const noexcept override
{
const int num = (int) numChannels;
if (map == nullptr || ! mappedSection.contains (sample))
{
jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
zeromem (result, sizeof (float) * (size_t) num);
return;
}
float** dest = &result;
const void* source = sampleToPointer (sample);
if (littleEndian)
{
switch (bitsPerSample)
{
case 8: ReadHelper<AudioData::Float32, AudioData::UInt8, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 16: ReadHelper<AudioData::Float32, AudioData::Int16, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 24: ReadHelper<AudioData::Float32, AudioData::Int24, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 32: if (usesFloatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num);
else ReadHelper<AudioData::Float32, AudioData::Int32, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
default: jassertfalse; break;
}
}
else
{
switch (bitsPerSample)
{
case 8: ReadHelper<AudioData::Float32, AudioData::UInt8, AudioData::BigEndian>::read (dest, 0, 1, source, 1, num); break;
case 16: ReadHelper<AudioData::Float32, AudioData::Int16, AudioData::BigEndian>::read (dest, 0, 1, source, 1, num); break;
case 24: ReadHelper<AudioData::Float32, AudioData::Int24, AudioData::BigEndian>::read (dest, 0, 1, source, 1, num); break;
case 32: if (usesFloatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, AudioData::BigEndian>::read (dest, 0, 1, source, 1, num);
else ReadHelper<AudioData::Float32, AudioData::Int32, AudioData::BigEndian>::read (dest, 0, 1, source, 1, num); break;
default: jassertfalse; break;
}
}
}
void readMaxLevels (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) override
{
if (numSamples <= 0)
{
min0 = max0 = min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = Range<float>();
return;
}
@@ -834,17 +901,19 @@ public:
{
jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
min0 = max0 = min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = Range<float>();
return;
}
switch (bitsPerSample)
{
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, min0, max0, min1, max1);
else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, results, numChannelsToRead);
else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, results, numChannelsToRead); break;
default: jassertfalse; break;
}
}
@@ -853,24 +922,17 @@ private:
const bool littleEndian;
template <typename SampleType>
void scanMinAndMax (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1) const noexcept
void scanMinAndMax (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) const noexcept
{
scanMinAndMax2<SampleType> (0, startSampleInFile, numSamples, min0, max0);
if (numChannels > 1)
scanMinAndMax2<SampleType> (1, startSampleInFile, numSamples, min1, max1);
else
min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = scanMinAndMaxForChannel<SampleType> (i, startSampleInFile, numSamples);
}
template <typename SampleType>
void scanMinAndMax2 (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept
Range<float> scanMinAndMaxForChannel (int channel, int64 startSampleInFile, int64 numSamples) const noexcept
{
if (littleEndian)
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (channel, startSampleInFile, numSamples, mn, mx);
else
scanMinAndMaxInterleaved<SampleType, AudioData::BigEndian> (channel, startSampleInFile, numSamples, mn, mx);
return littleEndian ? scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (channel, startSampleInFile, numSamples)
: scanMinAndMaxInterleaved<SampleType, AudioData::BigEndian> (channel, startSampleInFile, numSamples);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader)


+ 9
- 9
libs/juce/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp View File

@@ -607,7 +607,7 @@ private:
float* costab = cosTables[i];
for (int k = 0; k < kr; ++k)
costab[k] = (float) (1.0 / (2.0 * cos (double_Pi * (k * 2 + 1) / divv)));
costab[k] = (float) (1.0 / (2.0 * std::cos (double_Pi * (k * 2 + 1) / divv)));
}
for (i = 0, j = 0; i < 256; ++i, ++j, table += 32)
@@ -692,23 +692,23 @@ private:
for (i = 0; i < 18; ++i)
{
win[0][i] = win[1][i] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 19) / 72.0));
win[0][i + 18] = win[3][i + 18] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * (i + 18) + 1)) / cos (double_Pi * (2 * (i + 18) + 19) / 72.0));
win[0][i] = win[1][i] = (float) (0.5 * std::sin (double_Pi / 72.0 * (2 * i + 1)) / std::cos (double_Pi * (2 * i + 19) / 72.0));
win[0][i + 18] = win[3][i + 18] = (float) (0.5 * std::sin (double_Pi / 72.0 * (2 * (i + 18) + 1)) / std::cos (double_Pi * (2 * (i + 18) + 19) / 72.0));
}
const double piOver72 = double_Pi;
for (i = 0; i < 6; ++i)
{
win[1][i + 18] = (float) (0.5 / cos (piOver72 * (2 * (i + 18) + 19)));
win[3][i + 12] = (float) (0.5 / cos (piOver72 * (2 * (i + 12) + 19)));
win[1][i + 24] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 13)) / cos (piOver72 * (2 * (i + 24) + 19)));
win[1][i + 18] = (float) (0.5 / std::cos (piOver72 * (2 * (i + 18) + 19)));
win[3][i + 12] = (float) (0.5 / std::cos (piOver72 * (2 * (i + 12) + 19)));
win[1][i + 24] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 13)) / std::cos (piOver72 * (2 * (i + 24) + 19)));
win[1][i + 30] = win[3][i] = 0;
win[3][i + 6] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (piOver72 * (2 * (i + 6) + 19)));
win[3][i + 6] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 1)) / std::cos (piOver72 * (2 * (i + 6) + 19)));
}
for (i = 0; i < 12; ++i)
win[2][i] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 7) / 24.0));
win[2][i] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 1)) / std::cos (double_Pi * (2 * i + 7) / 24.0));
for (j = 0; j < 4; ++j)
{
@@ -721,7 +721,7 @@ private:
for (i = 0; i < 16; ++i)
{
const double t = tan (i * double_Pi / 12.0);
const double t = std::tan (i * double_Pi / 12.0);
tan1_1[i] = (float) (t / (1.0 + t));
tan2_1[i] = (float) (1.0 / (1.0 + t));
tan1_2[i] = (float) (sqrt2 * t / (1.0 + t));


+ 41
- 17
libs/juce/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp View File

@@ -1289,12 +1289,39 @@ public:
return true;
}
void readMaxLevels (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1) override
void getSample (int64 sample, float* result) const noexcept override
{
const int num = (int) numChannels;
if (map == nullptr || ! mappedSection.contains (sample))
{
jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
zeromem (result, sizeof (float) * (size_t) num);
return;
}
float** dest = &result;
const void* source = sampleToPointer (sample);
switch (bitsPerSample)
{
case 8: ReadHelper<AudioData::Float32, AudioData::UInt8, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 16: ReadHelper<AudioData::Float32, AudioData::Int16, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 24: ReadHelper<AudioData::Float32, AudioData::Int24, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
case 32: if (usesFloatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num);
else ReadHelper<AudioData::Float32, AudioData::Int32, AudioData::LittleEndian>::read (dest, 0, 1, source, 1, num); break;
default: jassertfalse; break;
}
}
void readMaxLevels (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) override
{
if (numSamples <= 0)
{
min0 = max0 = min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = Range<float>();
return;
}
@@ -1302,32 +1329,29 @@ public:
{
jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
min0 = max0 = min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = Range<float>();
return;
}
switch (bitsPerSample)
{
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, min0, max0, min1, max1);
else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, results, numChannelsToRead); break;
case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, results, numChannelsToRead);
else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, results, numChannelsToRead); break;
default: jassertfalse; break;
}
}
private:
template <typename SampleType>
void scanMinAndMax (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1) const noexcept
void scanMinAndMax (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) const noexcept
{
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (0, startSampleInFile, numSamples, min0, max0);
if (numChannels > 1)
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (1, startSampleInFile, numSamples, min1, max1);
else
min1 = max1 = 0;
for (int i = 0; i < numChannelsToRead; ++i)
results[i] = scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (i, startSampleInFile, numSamples);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedWavReader)


+ 13
- 11
libs/juce/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp View File

@@ -46,6 +46,7 @@ bool AudioFormatReader::read (int* const* destSamples,
{
jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
const size_t originalNumSamplesToRead = (size_t) numSamplesToRead;
int startOffsetInDestBuffer = 0;
if (startSampleInSource < 0)
@@ -64,7 +65,7 @@ bool AudioFormatReader::read (int* const* destSamples,
if (numSamplesToRead <= 0)
return true;
if (! readSamples (const_cast <int**> (destSamples),
if (! readSamples (const_cast<int**> (destSamples),
jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
startSampleInSource, numSamplesToRead))
return false;
@@ -87,13 +88,13 @@ bool AudioFormatReader::read (int* const* destSamples,
if (lastFullChannel != nullptr)
for (int i = (int) numChannels; i < numDestChannels; ++i)
if (destSamples[i] != nullptr)
memcpy (destSamples[i], lastFullChannel, sizeof (int) * (size_t) numSamplesToRead);
memcpy (destSamples[i], lastFullChannel, sizeof (int) * originalNumSamplesToRead);
}
else
{
for (int i = (int) numChannels; i < numDestChannels; ++i)
if (destSamples[i] != nullptr)
zeromem (destSamples[i], sizeof (int) * (size_t) numSamplesToRead);
zeromem (destSamples[i], sizeof (int) * originalNumSamplesToRead);
}
}
@@ -229,20 +230,21 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples
float& lowestRight, float& highestRight)
{
Range<float> levels[2];
readMaxLevels (startSampleInFile, numSamples, levels, jmin (2, (int) numChannels));
lowestLeft = levels[0].getStart();
highestLeft = levels[0].getEnd();
if (numChannels > 1)
if (numChannels < 2)
{
lowestRight = levels[1].getStart();
highestRight = levels[1].getEnd();
readMaxLevels (startSampleInFile, numSamples, levels, (int) numChannels);
levels[1] = levels[0];
}
else
{
lowestRight = lowestLeft;
highestRight = highestLeft;
readMaxLevels (startSampleInFile, numSamples, levels, 2);
}
lowestLeft = levels[0].getStart();
highestLeft = levels[0].getEnd();
lowestRight = levels[1].getStart();
highestRight = levels[1].getEnd();
}
int64 AudioFormatReader::searchForLevel (int64 startSample,


+ 3
- 3
libs/juce/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h View File

@@ -44,7 +44,7 @@ protected:
@param sourceStream the stream to read from - this will be deleted
by this object when it is no longer needed. (Some
specialised readers might not use this parameter and
can leave it as 0).
can leave it as nullptr).
@param formatName the description that will be returned by the getFormatName()
method
*/
@@ -247,8 +247,8 @@ protected:
template <class DestSampleType, class SourceSampleType, class SourceEndianness>
struct ReadHelper
{
typedef AudioData::Pointer <DestSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType;
typedef AudioData::Pointer <SourceSampleType, SourceEndianness, AudioData::Interleaved, AudioData::Const> SourceType;
typedef AudioData::Pointer<DestSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestType;
typedef AudioData::Pointer<SourceSampleType, SourceEndianness, AudioData::Interleaved, AudioData::Const> SourceType;
template <typename TargetType>
static void read (TargetType* const* destData, int destOffset, int numDestChannels,


+ 2
- 9
libs/juce/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp View File

@@ -57,17 +57,10 @@ bool AudioSubsectionReader::readSamples (int** destSamples, int numDestChannels,
startSampleInFile + startSample, numSamples);
}
void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile,
int64 numSamples,
float& lowestLeft,
float& highestLeft,
float& lowestRight,
float& highestRight)
void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead)
{
startSampleInFile = jmax ((int64) 0, startSampleInFile);
numSamples = jmax ((int64) 0, jmin (numSamples, length - startSampleInFile));
source->readMaxLevels (startSampleInFile + startSample, numSamples,
lowestLeft, highestLeft,
lowestRight, highestRight);
source->readMaxLevels (startSampleInFile + startSample, numSamples, results, numChannelsToRead);
}

+ 1
- 2
libs/juce/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h View File

@@ -68,8 +68,7 @@ public:
int64 startSampleInFile, int numSamples) override;
void readMaxLevels (int64 startSample, int64 numSamples,
float& lowestLeft, float& highestLeft,
float& lowestRight, float& highestRight) override;
Range<float>* results, int numChannelsToRead) override;
private:


+ 9
- 3
libs/juce/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h View File

@@ -70,6 +70,12 @@ public:
/** Touches the memory for the given sample, to force it to be loaded into active memory. */
void touchSample (int64 sample) const noexcept;
/** Returns the samples for all channels at a given sample position.
The result array must be large enough to hold a value for each channel
that this reader contains.
*/
virtual void getSample (int64 sampleIndex, float* result) const noexcept = 0;
/** Returns the number of bytes currently being mapped */
size_t getNumBytesUsed() const { return map != nullptr ? map->getSize() : 0; }
@@ -91,12 +97,12 @@ protected:
/** Used by AudioFormatReader subclasses to scan for min/max ranges in interleaved data. */
template <typename SampleType, typename Endianness>
void scanMinAndMaxInterleaved (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept
Range<float> scanMinAndMaxInterleaved (int channel, int64 startSampleInFile, int64 numSamples) const noexcept
{
typedef AudioData::Pointer <SampleType, Endianness, AudioData::Interleaved, AudioData::Const> SourceType;
SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), ((int) bitsPerSample / 8) * channel), (int) numChannels)
.findMinAndMax ((size_t) numSamples, mn, mx);
return SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), ((int) bitsPerSample / 8) * channel), (int) numChannels)
.findMinAndMax ((size_t) numSamples);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader)


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/juce_module_info View File

@@ -1,7 +1,7 @@
{
"id": "juce_audio_formats",
"name": "JUCE audio file format codecs",
"version": "3.0.8",
"version": "3.1.1",
"description": "Classes for reading and writing various audio file formats.",
"website": "http://www.juce.com/juce",
"license": "GPL/Commercial",


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp View File

@@ -119,7 +119,7 @@ void SamplerVoice::startNote (const int midiNoteNumber,
if (sound->releaseSamples > 0)
releaseDelta = (float) (-pitchRatio / sound->releaseSamples);
else
releaseDelta = 0.0f;
releaseDelta = -1.0f;
}
else
{


+ 14
- 4
libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp View File

@@ -495,6 +495,18 @@ struct AAXClasses
return AAX_CEffectParameters::SetChunk (chunkID, chunk);
pluginInstance->setStateInformation ((void*) chunk->fData, chunk->fSize);
// Notify Pro Tools that the parameters were updated.
// Without it a bug happens in these circumstances:
// * A preset is saved with the RTAS version of the plugin (".tfx" preset format).
// * The preset is loaded in PT 10 using the AAX version.
// * The session is then saved, and closed.
// * The saved session is loaded, but acting as if the preset was never loaded.
const int numParameters = pluginInstance->getNumParameters();
for (int i = 0; i < numParameters; ++i)
SetParameterNormalizedValue (IndexAsParamID (i), (double) pluginInstance->getParameter(i));
return AAX_SUCCESS;
}
@@ -781,10 +793,8 @@ struct AAXClasses
for (uint32_t i = 0; i < numMidiEvents; ++i)
{
// (This 8-byte alignment is a workaround to a bug in the AAX SDK. Hopefully can be
// removed in future when the packet structure size is fixed)
const AAX_CMidiPacket& m = *addBytesToPointer (midiStream->mBuffer,
i * ((sizeof (AAX_CMidiPacket) + 7) & ~(size_t) 7));
const AAX_CMidiPacket& m = midiStream->mBuffer[i];
jassert ((int) m.mTimestamp < bufferSize);
midiBuffer.addEvent (m.mData, (int) m.mLength,
jlimit (0, (int) bufferSize - 1, (int) m.mTimestamp));


+ 131
- 62
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -223,47 +223,57 @@ public:
{
switch (inID)
{
case juceFilterObjectPropertyID:
outWritable = false;
outDataSize = sizeof (void*) * 2;
return noErr;
case kAudioUnitProperty_OfflineRender:
outWritable = true;
outDataSize = sizeof (UInt32);
return noErr;
case kMusicDeviceProperty_InstrumentCount:
outDataSize = sizeof (UInt32);
outWritable = false;
return noErr;
case kAudioUnitProperty_CocoaUI:
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
// (On 10.4, there's a random obj-c dispatching crash when trying to load a cocoa UI)
if (SystemStats::getOperatingSystemType() >= SystemStats::MacOSX_10_5)
#endif
{
outDataSize = sizeof (AudioUnitCocoaViewInfo);
case juceFilterObjectPropertyID:
outWritable = false;
outDataSize = sizeof (void*) * 2;
return noErr;
case kAudioUnitProperty_OfflineRender:
outWritable = true;
outDataSize = sizeof (UInt32);
return noErr;
}
break;
case kMusicDeviceProperty_InstrumentCount:
outDataSize = sizeof (UInt32);
outWritable = false;
return noErr;
case kAudioUnitProperty_CocoaUI:
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
// (On 10.4, there's a random obj-c dispatching crash when trying to load a cocoa UI)
if (SystemStats::getOperatingSystemType() >= SystemStats::MacOSX_10_5)
#endif
{
outDataSize = sizeof (AudioUnitCocoaViewInfo);
outWritable = true;
return noErr;
}
#if JucePlugin_ProducesMidiOutput
case kAudioUnitProperty_MIDIOutputCallbackInfo:
outDataSize = sizeof (CFArrayRef);
outWritable = false;
return noErr;
break;
case kAudioUnitProperty_MIDIOutputCallback:
outDataSize = sizeof (AUMIDIOutputCallbackStruct);
outWritable = true;
return noErr;
#endif
#if JucePlugin_ProducesMidiOutput
case kAudioUnitProperty_MIDIOutputCallbackInfo:
outDataSize = sizeof (CFArrayRef);
outWritable = false;
return noErr;
default: break;
case kAudioUnitProperty_MIDIOutputCallback:
outDataSize = sizeof (AUMIDIOutputCallbackStruct);
outWritable = true;
return noErr;
#endif
case kAudioUnitProperty_ParameterStringFromValue:
outDataSize = sizeof (AudioUnitParameterStringFromValue);
outWritable = false;
return noErr;
case kAudioUnitProperty_ParameterValueFromString:
outDataSize = sizeof (AudioUnitParameterValueFromString);
outWritable = false;
return noErr;
default: break;
}
}
@@ -280,7 +290,7 @@ public:
switch (inID)
{
case juceFilterObjectPropertyID:
((void**) outData)[0] = (void*) static_cast <AudioProcessor*> (juceFilter);
((void**) outData)[0] = (void*) static_cast<AudioProcessor*> (juceFilter);
((void**) outData)[1] = (void*) this;
return noErr;
@@ -305,7 +315,7 @@ public:
// (NB: this may be the host's bundle, not necessarily the component's)
NSBundle* bundle = [NSBundle bundleForClass: cls.cls];
AudioUnitCocoaViewInfo* info = static_cast <AudioUnitCocoaViewInfo*> (outData);
AudioUnitCocoaViewInfo* info = static_cast<AudioUnitCocoaViewInfo*> (outData);
info->mCocoaAUViewClass[0] = (CFStringRef) [juceStringToNS (class_getName (cls.cls)) retain];
info->mCocoaAUViewBundleLocation = (CFURLRef) [[NSURL fileURLWithPath: [bundle bundlePath]] retain];
}
@@ -327,7 +337,48 @@ public:
}
#endif
default: break;
case kAudioUnitProperty_ParameterValueFromString:
{
if (AudioUnitParameterValueFromString* pv = (AudioUnitParameterValueFromString*) outData)
{
if (juceFilter != nullptr)
{
const String text (String::fromCFString (pv->inString));
if (AudioProcessorParameter* param = juceFilter->getParameters() [(int) pv->inParamID])
pv->outValue = param->getValueForText (text);
else
pv->outValue = text.getFloatValue();
return noErr;
}
}
}
break;
case kAudioUnitProperty_ParameterStringFromValue:
{
if (AudioUnitParameterStringFromValue* pv = (AudioUnitParameterStringFromValue*) outData)
{
if (juceFilter != nullptr)
{
const float value = (float) *(pv->inValue);
String text;
if (AudioProcessorParameter* param = juceFilter->getParameters() [(int) pv->inParamID])
text = param->getText ((float) *(pv->inValue), 0);
else
text = String (value);
pv->outString = text.toCFString();
return noErr;
}
}
}
break;
default:
break;
}
}
@@ -466,7 +517,8 @@ public:
{
outParameterInfo.flags = (UInt32) (kAudioUnitParameterFlag_IsWritable
| kAudioUnitParameterFlag_IsReadable
| kAudioUnitParameterFlag_HasCFNameString);
| kAudioUnitParameterFlag_HasCFNameString
| kAudioUnitParameterFlag_ValuesHaveStrings);
const String name (juceFilter->getParameterName (index));
@@ -606,9 +658,11 @@ public:
&outCurrentSampleInTimeLine,
&looping,
&outCycleStartBeat,
&outCycleEndBeat) != noErr)
&outCycleEndBeat) != noErr
|| getHostType().isLogic())
{
// If the host doesn't support this callback, use the sample time from lastTimeStamp:
// If the host doesn't support this callback (or if it's Logic, which has a bug),
// then fallback to using the sample time from lastTimeStamp:
outCurrentSampleInTimeLine = lastTimeStamp.mSampleTime;
}
@@ -647,7 +701,9 @@ public:
void audioProcessorChanged (AudioProcessor*)
{
PropertyChanged (kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0);
PropertyChanged (kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0);
PropertyChanged (kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0);
PropertyChanged (kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, 0);
}
bool StreamFormatWritable (AudioUnitScope, AudioUnitElement) override
@@ -664,9 +720,9 @@ public:
ComponentResult Initialize() override
{
#if ! JucePlugin_IsSynth
const int numIns = GetInput(0) != 0 ? (int) GetInput(0)->GetStreamFormat().mChannelsPerFrame : 0;
const int numIns = findNumInputChannels();
#endif
const int numOuts = GetOutput(0) != 0 ? (int) GetOutput(0)->GetStreamFormat().mChannelsPerFrame : 0;
const int numOuts = findNumOutputChannels();
bool isValidChannelConfig = false;
@@ -710,19 +766,32 @@ public:
return JuceAUBaseClass::Reset (inScope, inElement);
}
int findNumInputChannels()
{
#if ! JucePlugin_IsSynth
if (AUInputElement* e = GetInput(0))
return (int) e->GetStreamFormat().mChannelsPerFrame;
#endif
return 0;
}
int findNumOutputChannels()
{
if (AUOutputElement* e = GetOutput(0))
return (int) e->GetStreamFormat().mChannelsPerFrame;
return 0;
}
void prepareToPlay()
{
if (juceFilter != nullptr)
{
juceFilter->setPlayConfigDetails (
#if ! JucePlugin_IsSynth
(int) GetInput(0)->GetStreamFormat().mChannelsPerFrame,
#else
0,
#endif
(int) GetOutput(0)->GetStreamFormat().mChannelsPerFrame,
getSampleRate(),
(int) GetMaxFramesPerSlice());
juceFilter->setPlayConfigDetails (findNumInputChannels(),
findNumOutputChannels(),
getSampleRate(),
(int) GetMaxFramesPerSlice());
bufferSpace.setSize (juceFilter->getNumInputChannels() + juceFilter->getNumOutputChannels(),
(int) GetMaxFramesPerSlice() + 32);
@@ -1129,9 +1198,9 @@ public:
};
//==============================================================================
struct JuceUIViewClass : public ObjCClass <NSView>
struct JuceUIViewClass : public ObjCClass<NSView>
{
JuceUIViewClass() : ObjCClass <NSView> ("JUCEAUView_")
JuceUIViewClass() : ObjCClass<NSView> ("JUCEAUView_")
{
addIvar<AudioProcessor*> ("filter");
addIvar<JuceAU*> ("au");
@@ -1220,9 +1289,9 @@ public:
};
//==============================================================================
struct JuceUICreationClass : public ObjCClass <NSObject>
struct JuceUICreationClass : public ObjCClass<NSObject>
{
JuceUICreationClass() : ObjCClass <NSObject> ("JUCE_AUCocoaViewClass_")
JuceUICreationClass() : ObjCClass<NSObject> ("JUCE_AUCocoaViewClass_")
{
addMethod (@selector (interfaceVersion), interfaceVersion, @encode (unsigned int), "@:");
addMethod (@selector (description), description, @encode (NSString*), "@:");
@@ -1249,9 +1318,9 @@ public:
if (AudioUnitGetProperty (inAudioUnit, juceFilterObjectPropertyID,
kAudioUnitScope_Global, 0, pointers, &propertySize) == noErr)
{
if (AudioProcessor* filter = static_cast <AudioProcessor*> (pointers[0]))
if (AudioProcessor* filter = static_cast<AudioProcessor*> (pointers[0]))
if (AudioProcessorEditor* editorComp = filter->createEditorIfNeeded())
return EditorCompHolder::createViewFor (filter, static_cast <JuceAU*> (pointers[1]), editorComp);
return EditorCompHolder::createViewFor (filter, static_cast<JuceAU*> (pointers[1]), editorComp);
}
return nil;
@@ -1262,7 +1331,7 @@ private:
//==============================================================================
ScopedPointer<AudioProcessor> juceFilter;
AudioSampleBuffer bufferSpace;
HeapBlock <float*> channels;
HeapBlock<float*> channels;
MidiBuffer midiEvents, incomingEvents;
bool prepared;
AUChannelInfo channelInfo [numChannelConfigs];
@@ -1363,8 +1432,8 @@ private:
aren't so careful) */
jassert (Component::getCurrentlyModalComponent() == nullptr);
if (JuceAU::EditorCompHolder* editorCompHolder = dynamic_cast <JuceAU::EditorCompHolder*> (windowComp->getChildComponent(0)))
if (AudioProcessorEditor* audioProcessEditor = dynamic_cast <AudioProcessorEditor*> (editorCompHolder->getChildComponent(0)))
if (JuceAU::EditorCompHolder* editorCompHolder = dynamic_cast<JuceAU::EditorCompHolder*> (windowComp->getChildComponent(0)))
if (AudioProcessorEditor* audioProcessEditor = dynamic_cast<AudioProcessorEditor*> (editorCompHolder->getChildComponent(0)))
juceFilter->editorBeingDeleted (audioProcessEditor);
windowComp = nullptr;


+ 0
- 83
libs/juce/source/modules/juce_audio_plugin_client/LV2/base64/Base64.cpp View File

@@ -1,83 +0,0 @@
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
// source code was edited - removed everything not needed for juce-lv2
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
const String Base64Encode (const MemoryBlock &dataToEncode)
{
return (base64_encode ((unsigned char const *)dataToEncode.getData(), dataToEncode.getSize()).c_str());
}

+ 0
- 446
libs/juce/source/modules/juce_audio_plugin_client/LV2/includes/atom-util.h View File

@@ -1,446 +0,0 @@
/*
Copyright 2008-2013 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file util.h Helper functions for the LV2 Atom extension.

Note these functions are all static inline, do not take their address.

This header is non-normative, it is provided for convenience.
*/

#ifndef LV2_ATOM_UTIL_H
#define LV2_ATOM_UTIL_H

#include <stdarg.h>
#include <stdint.h>
#include <string.h>

#include "atom.h"

#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif

/** Pad a size to 64 bits. */
static inline uint32_t
lv2_atom_pad_size(uint32_t size)
{
return (size + 7U) & (~7U);
}

/** Return the total size of @p atom, including the header. */
static inline uint32_t
lv2_atom_total_size(const LV2_Atom* atom)
{
return (uint32_t)sizeof(LV2_Atom) + atom->size;
}

/** Return true iff @p atom is null. */
static inline bool
lv2_atom_is_null(const LV2_Atom* atom)
{
return !atom || (atom->type == 0 && atom->size == 0);
}

/** Return true iff @p a is equal to @p b. */
static inline bool
lv2_atom_equals(const LV2_Atom* a, const LV2_Atom* b)
{
return (a == b) || ((a->type == b->type) &&
(a->size == b->size) &&
!memcmp(a + 1, b + 1, a->size));
}

/**
@name Sequence Iterator
@{
*/

/** Get an iterator pointing to the first event in a Sequence body. */
static inline const LV2_Atom_Event*
lv2_atom_sequence_begin(const LV2_Atom_Sequence_Body* body)
{
return (const LV2_Atom_Event*)(body + 1);
}

/** Get an iterator pointing to the end of a Sequence body. */
static inline LV2_Atom_Event*
lv2_atom_sequence_end(LV2_Atom_Sequence_Body* body, uint32_t size)
{
return (LV2_Atom_Event*)((uint8_t*)body + lv2_atom_pad_size(size));
}

/** Return true iff @p i has reached the end of @p body. */
static inline bool
lv2_atom_sequence_is_end(const LV2_Atom_Sequence_Body* body,
uint32_t size,
const LV2_Atom_Event* i)
{
return (const uint8_t*)i >= ((const uint8_t*)body + size);
}

/** Return an iterator to the element following @p i. */
static inline const LV2_Atom_Event*
lv2_atom_sequence_next(const LV2_Atom_Event* i)
{
return (const LV2_Atom_Event*)((const uint8_t*)i
+ sizeof(LV2_Atom_Event)
+ lv2_atom_pad_size(i->body.size));
}

/**
A macro for iterating over all events in a Sequence.
@param seq The sequence to iterate over
@param iter The name of the iterator

This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_ATOM_SEQUENCE_FOREACH(sequence, ev) {
// Do something with ev (an LV2_Atom_Event*) here...
}
@endcode
*/
#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
for (const LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(&(seq)->body); \
!lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \
(iter) = lv2_atom_sequence_next(iter))

/** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */
#define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \
for (const LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(body); \
!lv2_atom_sequence_is_end(body, size, (iter)); \
(iter) = lv2_atom_sequence_next(iter))

/**
@}
@name Sequence Utilities
@{
*/

/**
Clear all events from @p sequence.

This simply resets the size field, the other fields are left untouched.
*/
static inline void
lv2_atom_sequence_clear(LV2_Atom_Sequence* seq)
{
seq->atom.size = sizeof(LV2_Atom_Sequence_Body);
}

/**
Append an event at the end of @p sequence.

@param seq Sequence to append to.
@param capacity Total capacity of the sequence atom
(e.g. as set by the host for sequence output ports).
@param event Event to write.

@return A pointer to the newly written event in @p seq,
or NULL on failure (insufficient space).
*/
static inline LV2_Atom_Event*
lv2_atom_sequence_append_event(LV2_Atom_Sequence* seq,
uint32_t capacity,
const LV2_Atom_Event* event)
{
const uint32_t total_size = (uint32_t)sizeof(*event) + event->body.size;
if (capacity - seq->atom.size < total_size) {
return NULL;
}

LV2_Atom_Event* e = lv2_atom_sequence_end(&seq->body, seq->atom.size);
memcpy(e, event, total_size);

seq->atom.size += lv2_atom_pad_size(total_size);

return e;
}

/**
@}
@name Tuple Iterator
@{
*/

/** Get an iterator pointing to the first element in @p tup. */
static inline const LV2_Atom*
lv2_atom_tuple_begin(const LV2_Atom_Tuple* tup)
{
return (const LV2_Atom*)(LV2_ATOM_BODY_CONST(tup));
}

/** Return true iff @p i has reached the end of @p body. */
static inline bool
lv2_atom_tuple_is_end(const void* body, uint32_t size, const LV2_Atom* i)
{
return (const uint8_t*)i >= ((const uint8_t*)body + size);
}

/** Return an iterator to the element following @p i. */
static inline const LV2_Atom*
lv2_atom_tuple_next(const LV2_Atom* i)
{
return (const LV2_Atom*)(
(const uint8_t*)i + sizeof(LV2_Atom) + lv2_atom_pad_size(i->size));
}

/**
A macro for iterating over all properties of a Tuple.
@param tuple The tuple to iterate over
@param iter The name of the iterator

This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_ATOMO_TUPLE_FOREACH(tuple, elem) {
// Do something with elem (an LV2_Atom*) here...
}
@endcode
*/
#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \
for (const LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \
!lv2_atom_tuple_is_end(LV2_ATOM_BODY_CONST(tuple), (tuple)->size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))

/** Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body. */
#define LV2_ATOM_TUPLE_BODY_FOREACH(body, size, iter) \
for (const LV2_Atom* (iter) = (const LV2_Atom*)body; \
!lv2_atom_tuple_is_end(body, size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))

/**
@}
@name Object Iterator
@{
*/

/** Return a pointer to the first property in @p body. */
static inline const LV2_Atom_Property_Body*
lv2_atom_object_begin(const LV2_Atom_Object_Body* body)
{
return (const LV2_Atom_Property_Body*)(body + 1);
}

/** Return true iff @p i has reached the end of @p obj. */
static inline bool
lv2_atom_object_is_end(const LV2_Atom_Object_Body* body,
uint32_t size,
const LV2_Atom_Property_Body* i)
{
return (const uint8_t*)i >= ((const uint8_t*)body + size);
}

/** Return an iterator to the property following @p i. */
static inline const LV2_Atom_Property_Body*
lv2_atom_object_next(const LV2_Atom_Property_Body* i)
{
const LV2_Atom* const value = (const LV2_Atom*)(
(const uint8_t*)i + 2 * sizeof(uint32_t));
return (const LV2_Atom_Property_Body*)(
(const uint8_t*)i + lv2_atom_pad_size(
(uint32_t)sizeof(LV2_Atom_Property_Body) + value->size));
}

/**
A macro for iterating over all properties of an Object.
@param obj The object to iterate over
@param iter The name of the iterator

This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_ATOM_OBJECT_FOREACH(object, i) {
// Do something with prop (an LV2_Atom_Property_Body*) here...
}
@endcode
*/
#define LV2_ATOM_OBJECT_FOREACH(obj, iter) \
for (const LV2_Atom_Property_Body* (iter) = lv2_atom_object_begin(&(obj)->body); \
!lv2_atom_object_is_end(&(obj)->body, (obj)->atom.size, (iter)); \
(iter) = lv2_atom_object_next(iter))

/** Like LV2_ATOM_OBJECT_FOREACH but for a headerless object body. */
#define LV2_ATOM_OBJECT_BODY_FOREACH(body, size, iter) \
for (const LV2_Atom_Property_Body* (iter) = lv2_atom_object_begin(body); \
!lv2_atom_object_is_end(body, size, (iter)); \
(iter) = lv2_atom_object_next(iter))

/**
@}
@name Object Query
@{
*/

/** A single entry in an Object query. */
typedef struct {
uint32_t key; /**< Key to query (input set by user) */
const LV2_Atom** value; /**< Found value (output set by query function) */
} LV2_Atom_Object_Query;

static const LV2_Atom_Object_Query LV2_ATOM_OBJECT_QUERY_END = { 0, NULL };

/**
Get an object's values for various keys.

The value pointer of each item in @p query will be set to the location of
the corresponding value in @p object. Every value pointer in @p query MUST
be initialised to NULL. This function reads @p object in a single linear
sweep. By allocating @p query on the stack, objects can be "queried"
quickly without allocating any memory. This function is realtime safe.

This function can only do "flat" queries, it is not smart enough to match
variables in nested objects.

For example:
@code
const LV2_Atom* name = NULL;
const LV2_Atom* age = NULL;
LV2_Atom_Object_Query q[] = {
{ urids.eg_name, &name },
{ urids.eg_age, &age },
LV2_ATOM_OBJECT_QUERY_END
};
lv2_atom_object_query(obj, q);
// name and age are now set to the appropriate values in obj, or NULL.
@endcode
*/
static inline int
lv2_atom_object_query(const LV2_Atom_Object* object,
LV2_Atom_Object_Query* query)
{
int matches = 0;
int n_queries = 0;

/* Count number of query keys so we can short-circuit when done */
for (LV2_Atom_Object_Query* q = query; q->key; ++q) {
++n_queries;
}

LV2_ATOM_OBJECT_FOREACH(object, prop) {
for (LV2_Atom_Object_Query* q = query; q->key; ++q) {
if (q->key == prop->key && !*q->value) {
*q->value = &prop->value;
if (++matches == n_queries) {
return matches;
}
break;
}
}
}
return matches;
}

/**
Body only version of lv2_atom_object_get().
*/
static inline int
lv2_atom_object_body_get(uint32_t size, const LV2_Atom_Object_Body* body, ...)
{
int matches = 0;
int n_queries = 0;

/* Count number of keys so we can short-circuit when done */
va_list args;
va_start(args, body);
for (n_queries = 0; va_arg(args, uint32_t); ++n_queries) {
if (!va_arg(args, const LV2_Atom**)) {
return -1;
}
}
va_end(args);

LV2_ATOM_OBJECT_BODY_FOREACH(body, size, prop) {
va_start(args, body);
for (int i = 0; i < n_queries; ++i) {
uint32_t qkey = va_arg(args, uint32_t);
const LV2_Atom** qval = va_arg(args, const LV2_Atom**);
if (qkey == prop->key && !*qval) {
*qval = &prop->value;
if (++matches == n_queries) {
return matches;
}
break;
}
}
va_end(args);
}
return matches;
}

/**
Variable argument version of lv2_atom_object_query().

This is nicer-looking in code, but a bit more error-prone since it is not
type safe and the argument list must be terminated.

The arguments should be a series of uint32_t key and const LV2_Atom** value
pairs, terminated by a zero key. The value pointers MUST be initialized to
NULL. For example:

@code
const LV2_Atom* name = NULL;
const LV2_Atom* age = NULL;
lv2_atom_object_get(obj,
uris.name_key, &name,
uris.age_key, &age,
0);
@endcode
*/
static inline int
lv2_atom_object_get(const LV2_Atom_Object* object, ...)
{
int matches = 0;
int n_queries = 0;

/* Count number of keys so we can short-circuit when done */
va_list args;
va_start(args, object);
for (n_queries = 0; va_arg(args, uint32_t); ++n_queries) {
if (!va_arg(args, const LV2_Atom**)) {
return -1;
}
}
va_end(args);

LV2_ATOM_OBJECT_FOREACH(object, prop) {
va_start(args, object);
for (int i = 0; i < n_queries; ++i) {
uint32_t qkey = va_arg(args, uint32_t);
const LV2_Atom** qval = va_arg(args, const LV2_Atom**);
if (qkey == prop->key && !*qval) {
*qval = &prop->value;
if (++matches == n_queries) {
return matches;
}
break;
}
}
va_end(args);
}
return matches;
}

/**
@}
*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* LV2_ATOM_UTIL_H */

+ 0
- 246
libs/juce/source/modules/juce_audio_plugin_client/LV2/includes/atom.h View File

@@ -1,246 +0,0 @@
/*
Copyright 2008-2012 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file atom.h C header for the LV2 Atom extension
<http://lv2plug.in/ns/ext/atom>.
*/

#ifndef LV2_ATOM_H
#define LV2_ATOM_H

#include <stdint.h>
#include <stddef.h>

#define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom"
#define LV2_ATOM_PREFIX LV2_ATOM_URI "#"

#define LV2_ATOM__Atom LV2_ATOM_PREFIX "Atom"
#define LV2_ATOM__AtomPort LV2_ATOM_PREFIX "AtomPort"
#define LV2_ATOM__Blank LV2_ATOM_PREFIX "Blank"
#define LV2_ATOM__Bool LV2_ATOM_PREFIX "Bool"
#define LV2_ATOM__Chunk LV2_ATOM_PREFIX "Chunk"
#define LV2_ATOM__Double LV2_ATOM_PREFIX "Double"
#define LV2_ATOM__Event LV2_ATOM_PREFIX "Event"
#define LV2_ATOM__Float LV2_ATOM_PREFIX "Float"
#define LV2_ATOM__Int LV2_ATOM_PREFIX "Int"
#define LV2_ATOM__Literal LV2_ATOM_PREFIX "Literal"
#define LV2_ATOM__Long LV2_ATOM_PREFIX "Long"
#define LV2_ATOM__Number LV2_ATOM_PREFIX "Number"
#define LV2_ATOM__Object LV2_ATOM_PREFIX "Object"
#define LV2_ATOM__Path LV2_ATOM_PREFIX "Path"
#define LV2_ATOM__Property LV2_ATOM_PREFIX "Property"
#define LV2_ATOM__Resource LV2_ATOM_PREFIX "Resource"
#define LV2_ATOM__Sequence LV2_ATOM_PREFIX "Sequence"
#define LV2_ATOM__Sound LV2_ATOM_PREFIX "Sound"
#define LV2_ATOM__String LV2_ATOM_PREFIX "String"
#define LV2_ATOM__Tuple LV2_ATOM_PREFIX "Tuple"
#define LV2_ATOM__URI LV2_ATOM_PREFIX "URI"
#define LV2_ATOM__URID LV2_ATOM_PREFIX "URID"
#define LV2_ATOM__Vector LV2_ATOM_PREFIX "Vector"
#define LV2_ATOM__atomTransfer LV2_ATOM_PREFIX "atomTransfer"
#define LV2_ATOM__beatTime LV2_ATOM_PREFIX "beatTime"
#define LV2_ATOM__bufferType LV2_ATOM_PREFIX "bufferType"
#define LV2_ATOM__childType LV2_ATOM_PREFIX "childType"
#define LV2_ATOM__eventTransfer LV2_ATOM_PREFIX "eventTransfer"
#define LV2_ATOM__frameTime LV2_ATOM_PREFIX "frameTime"
#define LV2_ATOM__supports LV2_ATOM_PREFIX "supports"
#define LV2_ATOM__timeUnit LV2_ATOM_PREFIX "timeUnit"

#define LV2_ATOM_REFERENCE_TYPE 0

#ifdef __cplusplus
extern "C" {
#endif

/** This expression will fail to compile if double does not fit in 64 bits. */
typedef char lv2_atom_assert_double_fits_in_64_bits[
((sizeof(double) <= sizeof(uint64_t)) * 2) - 1];

/**
Return a pointer to the contents of an Atom. The "contents" of an atom
is the data past the complete type-specific header.
@param type The type of the atom, e.g. LV2_Atom_String.
@param atom A variable-sized atom.
*/
#define LV2_ATOM_CONTENTS(type, atom) \
((uint8_t*)(atom) + sizeof(type))

/**
Const version of LV2_ATOM_CONTENTS.
*/
#define LV2_ATOM_CONTENTS_CONST(type, atom) \
((const uint8_t*)(atom) + sizeof(type))

/**
Return a pointer to the body of an Atom. The "body" of an atom is the
data just past the LV2_Atom head (i.e. the same offset for all types).
*/
#define LV2_ATOM_BODY(atom) LV2_ATOM_CONTENTS(LV2_Atom, atom)

/**
Const version of LV2_ATOM_BODY.
*/
#define LV2_ATOM_BODY_CONST(atom) LV2_ATOM_CONTENTS_CONST(LV2_Atom, atom)

/** The header of an atom:Atom. */
typedef struct {
uint32_t size; /**< Size in bytes, not including type and size. */
uint32_t type; /**< Type of this atom (mapped URI). */
} LV2_Atom;

/** An atom:Int or atom:Bool. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
int32_t body; /**< Integer value. */
} LV2_Atom_Int;

/** An atom:Long. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
int64_t body; /**< Integer value. */
} LV2_Atom_Long;

/** An atom:Float. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
float body; /**< Floating point value. */
} LV2_Atom_Float;

/** An atom:Double. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
double body; /**< Floating point value. */
} LV2_Atom_Double;

/** An atom:Bool. May be cast to LV2_Atom. */
typedef LV2_Atom_Int LV2_Atom_Bool;

/** An atom:URID. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
uint32_t body; /**< URID. */
} LV2_Atom_URID;

/** An atom:String. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
/* Contents (a null-terminated UTF-8 string) follow here. */
} LV2_Atom_String;

/** The body of an atom:Literal. */
typedef struct {
uint32_t datatype; /**< Datatype URID. */
uint32_t lang; /**< Language URID. */
/* Contents (a null-terminated UTF-8 string) follow here. */
} LV2_Atom_Literal_Body;

/** An atom:Literal. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Literal_Body body; /**< Body. */
} LV2_Atom_Literal;

/** An atom:Tuple. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
/* Contents (a series of complete atoms) follow here. */
} LV2_Atom_Tuple;

/** The body of an atom:Vector. */
typedef struct {
uint32_t child_size; /**< The size of each element in the vector. */
uint32_t child_type; /**< The type of each element in the vector. */
/* Contents (a series of packed atom bodies) follow here. */
} LV2_Atom_Vector_Body;

/** An atom:Vector. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Vector_Body body; /**< Body. */
} LV2_Atom_Vector;

/** The body of an atom:Property (e.g. in an atom:Object). */
typedef struct {
uint32_t key; /**< Key (predicate) (mapped URI). */
uint32_t context; /**< Context URID (may be, and generally is, 0). */
LV2_Atom value; /**< Value atom header. */
/* Value atom body follows here. */
} LV2_Atom_Property_Body;

/** An atom:Property. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Property_Body body; /**< Body. */
} LV2_Atom_Property;

/** The body of an atom:Object. May be cast to LV2_Atom. */
typedef struct {
uint32_t id; /**< URID, or 0 for blank. */
uint32_t otype; /**< Type URID (same as rdf:type, for fast dispatch). */
/* Contents (a series of property bodies) follow here. */
} LV2_Atom_Object_Body;

/** An atom:Object. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Object_Body body; /**< Body. */
} LV2_Atom_Object;

/** The header of an atom:Event. Note this type is NOT an LV2_Atom. */
typedef struct {
/** Time stamp. Which type is valid is determined by context. */
union {
int64_t frames; /**< Time in audio frames. */
double beats; /**< Time in beats. */
} time;
LV2_Atom body; /**< Event body atom header. */
/* Body atom contents follow here. */
} LV2_Atom_Event;

/**
The body of an atom:Sequence (a sequence of events).

The unit field is either a URID that described an appropriate time stamp
type, or may be 0 where a default stamp type is known. For
LV2_Descriptor::run(), the default stamp type is audio frames.

The contents of a sequence is a series of LV2_Atom_Event, each aligned
to 64-bits, e.g.:
<pre>
| Event 1 (size 6) | Event 2
| | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|FRAMES |SUBFRMS|TYPE |SIZE |DATADATADATAPAD|FRAMES |SUBFRMS|...
</pre>
*/
typedef struct {
uint32_t unit; /**< URID of unit of event time stamps. */
uint32_t pad; /**< Currently unused. */
/* Contents (a series of events) follow here. */
} LV2_Atom_Sequence_Body;

/** An atom:Sequence. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Sequence_Body body; /**< Body. */
} LV2_Atom_Sequence;

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* LV2_ATOM_H */

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save