Browse Source

Update juce

tags/2018-04-16
falkTX 9 years ago
parent
commit
75bbdc9c97
100 changed files with 2109 additions and 992 deletions
  1. +0
    -2
      libs/juce-plugin/JucePluginMain.h
  2. +1
    -1
      libs/juce/build-juce/AppConfig.h
  3. +9
    -22
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  4. +6
    -0
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
  5. +63
    -0
      libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp
  6. +89
    -0
      libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h
  7. +133
    -139
      libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp
  8. +4
    -9
      libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h
  9. +4
    -4
      libs/juce/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h
  10. +1
    -2
      libs/juce/source/modules/juce_audio_basics/juce_audio_basics.cpp
  11. +2
    -1
      libs/juce/source/modules/juce_audio_basics/juce_audio_basics.h
  12. +1
    -1
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  13. +16
    -5
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp
  14. +10
    -1
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h
  15. +2
    -2
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp
  16. +6
    -6
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiRPN.h
  17. +5
    -13
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp
  18. +14
    -17
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h
  19. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp
  20. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp
  21. +6
    -6
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPENote.h
  22. +9
    -9
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h
  23. +10
    -10
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h
  24. +4
    -4
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h
  25. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp
  26. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEValue.h
  27. +3
    -3
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp
  28. +1
    -1
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZone.h
  29. +0
    -8
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp
  30. +4
    -7
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h
  31. +1
    -1
      libs/juce/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h
  32. +11
    -8
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  33. +8
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h
  34. +6
    -5
      libs/juce/source/modules/juce_audio_devices/juce_audio_devices.cpp
  35. +3
    -3
      libs/juce/source/modules/juce_audio_devices/juce_audio_devices.h
  36. +39
    -13
      libs/juce/source/modules/juce_audio_devices/native/juce_android_Audio.cpp
  37. +31
    -11
      libs/juce/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp
  38. +27
    -22
      libs/juce/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp
  39. +64
    -38
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  40. +36
    -27
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp
  41. +5
    -0
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp
  42. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h
  43. +18
    -9
      libs/juce/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp
  44. +0
    -4
      libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp
  45. +4
    -10
      libs/juce/source/modules/juce_audio_formats/juce_audio_formats.cpp
  46. +2
    -2
      libs/juce/source/modules/juce_audio_formats/juce_audio_formats.h
  47. +102
    -16
      libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
  48. +200
    -65
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  49. +0
    -2
      libs/juce/source/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h
  50. +14
    -18
      libs/juce/source/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp
  51. +32
    -13
      libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  52. +199
    -145
      libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
  53. +7
    -5
      libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm
  54. +12
    -7
      libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
  55. +0
    -1
      libs/juce/source/modules/juce_audio_plugin_client/juce_audio_plugin_client.h
  56. +5
    -4
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h
  57. +5
    -5
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
  58. +0
    -9
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h
  59. +16
    -2
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginBusUtilities.h
  60. +31
    -25
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h
  61. +0
    -1
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp
  62. +0
    -5
      libs/juce/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  63. +0
    -1
      libs/juce/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
  64. +39
    -39
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3Common.h
  65. +0
    -8
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h
  66. +3
    -11
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  67. +5
    -10
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  68. +2
    -5
      libs/juce/source/modules/juce_audio_processors/juce_audio_processors.cpp
  69. +3
    -3
      libs/juce/source/modules/juce_audio_processors/juce_audio_processors.h
  70. +18
    -12
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp
  71. +2
    -2
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h
  72. +14
    -12
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
  73. +16
    -8
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h
  74. +0
    -6
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  75. +0
    -2
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  76. +14
    -17
      libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp
  77. +6
    -6
      libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
  78. +1
    -1
      libs/juce/source/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h
  79. +7
    -0
      libs/juce/source/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp
  80. +3
    -0
      libs/juce/source/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h
  81. +3
    -2
      libs/juce/source/modules/juce_audio_utils/juce_audio_utils.cpp
  82. +1
    -1
      libs/juce/source/modules/juce_audio_utils/juce_audio_utils.h
  83. +19
    -10
      libs/juce/source/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp
  84. +7
    -0
      libs/juce/source/modules/juce_core/containers/juce_HashMap.h
  85. +62
    -22
      libs/juce/source/modules/juce_core/files/juce_File.cpp
  86. +1
    -1
      libs/juce/source/modules/juce_core/files/juce_File.h
  87. +2
    -2
      libs/juce/source/modules/juce_core/files/juce_WildcardFileFilter.h
  88. +57
    -8
      libs/juce/source/modules/juce_core/javascript/juce_Javascript.cpp
  89. +7
    -6
      libs/juce/source/modules/juce_core/juce_core.cpp
  90. +25
    -6
      libs/juce/source/modules/juce_core/juce_core.h
  91. +1
    -1
      libs/juce/source/modules/juce_core/maths/juce_BigInteger.cpp
  92. +10
    -6
      libs/juce/source/modules/juce_core/maths/juce_MathsFunctions.h
  93. +145
    -0
      libs/juce/source/modules/juce_core/maths/juce_StatisticsAccumulator.h
  94. +1
    -1
      libs/juce/source/modules/juce_core/memory/juce_Atomic.h
  95. +1
    -1
      libs/juce/source/modules/juce_core/memory/juce_ByteOrder.h
  96. +6
    -0
      libs/juce/source/modules/juce_core/memory/juce_OptionalScopedPointer.h
  97. +48
    -0
      libs/juce/source/modules/juce_core/misc/juce_RuntimePermissions.cpp
  98. +131
    -0
      libs/juce/source/modules/juce_core/misc/juce_RuntimePermissions.h
  99. +14
    -0
      libs/juce/source/modules/juce_core/native/java/AndroidRuntimePermissions.java
  100. +145
    -23
      libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java

+ 0
- 2
libs/juce-plugin/JucePluginMain.h View File

@@ -25,6 +25,4 @@
#include "modules/juce_gui_extra/juce_gui_extra.h"
#include "modules/juce_tracktion_marketplace/juce_tracktion_marketplace.h"

#include "modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h"

#endif // JUCE_PLUGIN_MAIN_H_INCLUDED

+ 1
- 1
libs/juce/build-juce/AppConfig.h View File

@@ -139,7 +139,7 @@
@see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU, JUCE_PLUGINHOST_VST3
*/
#define JUCE_PLUGINHOST_VST 0
#define JUCE_PLUGINHOST_VST 1
/** Config: JUCE_PLUGINHOST_VST3
Enables the VST3 audio plugin hosting classes. This requires the Steinberg VST3 SDK to be


+ 9
- 22
libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -29,17 +29,6 @@ namespace FloatVectorHelpers
#define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest));
#if JUCE_USE_SSE_INTRINSICS
static bool sse2Present = false;
static bool isSSE2Available() noexcept
{
if (sse2Present)
return true;
sse2Present = SystemStats::hasSSE2();
return sse2Present;
}
inline static bool isAligned (const void* p) noexcept
{
return (((pointer_sized_int) p) & 15) == 0;
@@ -113,7 +102,6 @@ namespace FloatVectorHelpers
#define JUCE_BEGIN_VEC_OP \
typedef FloatVectorHelpers::ModeType<sizeof(*dest)>::Mode Mode; \
if (FloatVectorHelpers::isSSE2Available()) \
{ \
const int numLongOps = num / Mode::numParallel;
@@ -372,11 +360,7 @@ namespace FloatVectorHelpers
{
int numLongOps = num / Mode::numParallel;
#if JUCE_USE_SSE_INTRINSICS
if (numLongOps > 1 && isSSE2Available())
#else
if (numLongOps > 1)
#endif
{
ParallelType val;
@@ -446,11 +430,7 @@ namespace FloatVectorHelpers
{
int numLongOps = num / Mode::numParallel;
#if JUCE_USE_SSE_INTRINSICS
if (numLongOps > 1 && isSSE2Available())
#else
if (numLongOps > 1)
#endif
{
ParallelType mn, mx;
@@ -1002,12 +982,19 @@ double JUCE_CALLTYPE FloatVectorOperations::findMaximum (const double* src, int
void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept
{
#if JUCE_USE_SSE_INTRINSICS
if (FloatVectorHelpers::isSSE2Available())
_MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF);
_MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF);
#endif
ignoreUnused (shouldEnable);
}
void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noexcept
{
#if JUCE_USE_SSE_INTRINSICS
const int mxcsr = _mm_getcsr();
_mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits
#endif
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS


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

@@ -198,6 +198,12 @@ public:
Effectively, this is a wrapper around a call to _MM_SET_FLUSH_ZERO_MODE
*/
static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept;
/** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes.
This effectively sets the DAZ and FZ bits of the MXCSR register. It's a convenient thing to
call before audio processing code where you really want to avoid denormalisation performance hits.
*/
static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept;
};


+ 63
- 0
libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp View File

@@ -0,0 +1,63 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI 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.
==============================================================================
*/
struct CatmullRomAlgorithm
{
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
{
const float y0 = inputs[3];
const float y1 = inputs[2];
const float y2 = inputs[1];
const float y3 = inputs[0];
const float halfY0 = 0.5f * y0;
const float halfY3 = 0.5f * y3;
return y1 + offset * ((0.5f * y2 - halfY0)
+ (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1))
+ (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2))))));
}
};
CatmullRomInterpolator::CatmullRomInterpolator() noexcept { reset(); }
CatmullRomInterpolator::~CatmullRomInterpolator() noexcept {}
void CatmullRomInterpolator::reset() noexcept
{
subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
}
int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept
{
return interpolate<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut);
}
int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept
{
return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain);
}

+ 89
- 0
libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h View File

@@ -0,0 +1,89 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI 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.
==============================================================================
*/
/**
Interpolator for resampling a stream of floats using Catmull-Rom interpolation.
Note that the resampler is stateful, so when there's a break in the continuity
of the input stream you're feeding it, you should call reset() before feeding
it any new data. And like with any other stateful filter, if you're resampling
multiple channels, make sure each one uses its own CatmullRomInterpolator
object.
@see LagrangeInterpolator
*/
class JUCE_API CatmullRomInterpolator
{
public:
CatmullRomInterpolator() noexcept;
~CatmullRomInterpolator() noexcept;
/** Resets the state of the interpolator.
Call this when there's a break in the continuity of the input data stream.
*/
void reset() noexcept;
/** Resamples a stream of samples.
@param speedRatio the number of input samples to use for each output sample
@param inputSamples the source data to read from. This must contain at
least (speedRatio * numOutputSamplesToProduce) samples.
@param outputSamples the buffer to write the results into
@param numOutputSamplesToProduce the number of output samples that should be created
@returns the actual number of input samples that were used
*/
int process (double speedRatio,
const float* inputSamples,
float* outputSamples,
int numOutputSamplesToProduce) noexcept;
/** Resamples a stream of samples, adding the results to the output data
with a gain.
@param speedRatio the number of input samples to use for each output sample
@param inputSamples the source data to read from. This must contain at
least (speedRatio * numOutputSamplesToProduce) samples.
@param outputSamples the buffer to write the results to - the result values will be added
to any pre-existing data in this buffer after being multiplied by
the gain factor
@param numOutputSamplesToProduce the number of output samples that should be created
@param gain a gain factor to multiply the resulting samples by before
adding them to the destination buffer
@returns the actual number of input samples that were used
*/
int processAdding (double speedRatio,
const float* inputSamples,
float* outputSamples,
int numOutputSamplesToProduce,
float gain) noexcept;
private:
float lastInputSamples[5];
double subSamplePos;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator)
};

+ 133
- 139
libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp View File

@@ -22,185 +22,179 @@
==============================================================================
*/
namespace LagrangeHelpers
namespace
{
template <int k>
struct ResampleHelper
{
static forcedinline void calc (float& a, float b) { a *= b * (1.0f / k); }
};
template<>
struct ResampleHelper <0>
{
static forcedinline void calc (float&, float) {}
};
template <int k>
static forcedinline float calcCoefficient (float input, const float offset) noexcept
static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept
{
ResampleHelper <0 - k>::calc (input, -2.0f - offset);
ResampleHelper <1 - k>::calc (input, -1.0f - offset);
ResampleHelper <2 - k>::calc (input, 0.0f - offset);
ResampleHelper <3 - k>::calc (input, 1.0f - offset);
ResampleHelper <4 - k>::calc (input, 2.0f - offset);
return input;
lastInputSamples[4] = lastInputSamples[3];
lastInputSamples[3] = lastInputSamples[2];
lastInputSamples[2] = lastInputSamples[1];
lastInputSamples[1] = lastInputSamples[0];
lastInputSamples[0] = newValue;
}
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
{
return calcCoefficient<0> (inputs[4], offset)
+ calcCoefficient<1> (inputs[3], offset)
+ calcCoefficient<2> (inputs[2], offset)
+ calcCoefficient<3> (inputs[1], offset)
+ calcCoefficient<4> (inputs[0], offset);
}
static forcedinline void push (float* inputs, const float newValue) noexcept
{
inputs[4] = inputs[3];
inputs[3] = inputs[2];
inputs[2] = inputs[1];
inputs[1] = inputs[0];
inputs[0] = newValue;
}
}
//==============================================================================
LagrangeInterpolator::LagrangeInterpolator() { reset(); }
LagrangeInterpolator::~LagrangeInterpolator() {}
void LagrangeInterpolator::reset() noexcept
{
subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
}
int LagrangeInterpolator::process (const double actualRatio, const float* in,
float* out, const int numOut) noexcept
{
if (actualRatio == 1.0)
static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, int numOut) noexcept
{
memcpy (out, in, (size_t) numOut * sizeof (float));
if (numOut >= 4)
if (numOut >= 5)
{
const float* end = in + numOut;
for (int i = 0; i < 4; ++i)
lastInputSamples[i] = *--end;
for (int i = 0; i < 5; ++i)
lastInputSamples[i] = input[--numOut];
}
else
{
for (int i = 0; i < numOut; ++i)
LagrangeHelpers::push (lastInputSamples, in[i]);
pushInterpolationSample (lastInputSamples, input[i]);
}
return numOut;
}
const float* const originalIn = in;
double pos = subSamplePos;
if (actualRatio < 1.0)
template <typename InterpolatorType>
static int interpolate (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut) noexcept
{
for (int i = numOut; --i >= 0;)
if (actualRatio == 1.0)
{
if (pos >= 1.0)
memcpy (out, in, (size_t) numOut * sizeof (float));
pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut;
}
const float* const originalIn = in;
double pos = subSamplePos;
if (actualRatio < 1.0)
{
for (int i = numOut; --i >= 0;)
{
LagrangeHelpers::push (lastInputSamples, *in++);
pos -= 1.0;
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
*out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = numOut; --i >= 0;)
else
{
while (pos < actualRatio)
for (int i = numOut; --i >= 0;)
{
LagrangeHelpers::push (lastInputSamples, *in++);
pos += 1.0;
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
}
pos -= actualRatio;
*out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, 1.0f - (float) pos);
}
}
subSamplePos = pos;
return (int) (in - originalIn);
}
subSamplePos = pos;
return (int) (in - originalIn);
}
int LagrangeInterpolator::processAdding (const double actualRatio, const float* in,
float* out, const int numOut, const float gain) noexcept
{
if (actualRatio == 1.0)
template <typename InterpolatorType>
static int interpolateAdding (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut, const float gain) noexcept
{
if (gain != 1.0f)
{
for (int i = 0; i < numOut; ++i)
out[i] += in[i] * gain;
}
else
if (actualRatio == 1.0)
{
for (int i = 0; i < numOut; ++i)
out[i] += in[i];
FloatVectorOperations::addWithMultiply (out, in, gain, numOut);
pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut;
}
if (numOut >= 4)
{
const float* end = in + numOut;
const float* const originalIn = in;
double pos = subSamplePos;
for (int i = 0; i < 4; ++i)
lastInputSamples[i] = *--end;
if (actualRatio < 1.0)
{
for (int i = numOut; --i >= 0;)
{
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = 0; i < numOut; ++i)
LagrangeHelpers::push (lastInputSamples, in[i]);
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
}
}
return numOut;
subSamplePos = pos;
return (int) (in - originalIn);
}
}
const float* const originalIn = in;
double pos = subSamplePos;
//==============================================================================
template <int k>
struct LagrangeResampleHelper
{
static forcedinline void calc (float& a, float b) noexcept { a *= b * (1.0f / k); }
};
if (actualRatio < 1.0)
{
for (int i = numOut; --i >= 0;)
{
if (pos >= 1.0)
{
LagrangeHelpers::push (lastInputSamples, *in++);
pos -= 1.0;
}
template<>
struct LagrangeResampleHelper<0>
{
static forcedinline void calc (float&, float) noexcept {}
};
*out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
struct LagrangeAlgorithm
{
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
{
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
LagrangeHelpers::push (lastInputSamples, *in++);
pos += 1.0;
}
return calcCoefficient<0> (inputs[4], offset)
+ calcCoefficient<1> (inputs[3], offset)
+ calcCoefficient<2> (inputs[2], offset)
+ calcCoefficient<3> (inputs[1], offset)
+ calcCoefficient<4> (inputs[0], offset);
}
pos -= actualRatio;
*out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
}
template <int k>
static forcedinline float calcCoefficient (float input, const float offset) noexcept
{
LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset);
LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset);
LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset);
LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset);
LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset);
return input;
}
};
LagrangeInterpolator::LagrangeInterpolator() noexcept { reset(); }
LagrangeInterpolator::~LagrangeInterpolator() noexcept {}
subSamplePos = pos;
return (int) (in - originalIn);
void LagrangeInterpolator::reset() noexcept
{
subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
}
int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept
{
return interpolate<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut);
}
int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept
{
return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain);
}

+ 4
- 9
libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h View File

@@ -22,11 +22,7 @@
==============================================================================
*/
#ifndef JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED
#define JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED
//==============================================================================
/**
Interpolator for resampling a stream of floats using 4-point lagrange interpolation.
@@ -35,12 +31,14 @@
it any new data. And like with any other stateful filter, if you're resampling
multiple channels, make sure each one uses its own LagrangeInterpolator
object.
@see CatmullRomInterpolator
*/
class JUCE_API LagrangeInterpolator
{
public:
LagrangeInterpolator();
~LagrangeInterpolator();
LagrangeInterpolator() noexcept;
~LagrangeInterpolator() noexcept;
/** Resets the state of the interpolator.
Call this when there's a break in the continuity of the input data stream.
@@ -89,6 +87,3 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator)
};
#endif // JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED

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

@@ -49,7 +49,7 @@ public:
{
}
//==========================================================================
//==============================================================================
/** Reset to a new sample rate and ramp length. */
void reset (double sampleRate, double rampLengthInSeconds) noexcept
{
@@ -59,7 +59,7 @@ public:
countdown = 0;
}
//==========================================================================
//==============================================================================
/** Set a new target value. */
void setValue (FloatType newValue) noexcept
{
@@ -75,7 +75,7 @@ public:
}
}
//==========================================================================
//==============================================================================
/** Compute the next value. */
FloatType getNextValue() noexcept
{
@@ -88,7 +88,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
FloatType currentValue, target, step;
int countdown, stepsToTarget;
};


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

@@ -58,9 +58,7 @@
#endif
#if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK
#define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers)
#include <Accelerate/Accelerate.h>
#undef Point
#else
#undef JUCE_USE_VDSP_FRAMEWORK
#endif
@@ -81,6 +79,7 @@ namespace juce
#include "effects/juce_IIRFilter.cpp"
#include "effects/juce_IIRFilterOld.cpp"
#include "effects/juce_LagrangeInterpolator.cpp"
#include "effects/juce_CatmullRomInterpolator.cpp"
#include "effects/juce_FFT.cpp"
#include "midi/juce_MidiBuffer.cpp"
#include "midi/juce_MidiFile.cpp"


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

@@ -27,7 +27,7 @@
#include "../juce_core/juce_core.h"
//=============================================================================
//==============================================================================
namespace juce
{
@@ -41,6 +41,7 @@ namespace juce
#include "effects/juce_IIRFilter.h"
#include "effects/juce_IIRFilterOld.h"
#include "effects/juce_LagrangeInterpolator.h"
#include "effects/juce_CatmullRomInterpolator.h"
#include "effects/juce_FFT.h"
#include "effects/juce_LinearSmoothedValue.h"
#include "effects/juce_Reverb.h"


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

@@ -371,7 +371,7 @@ int MidiMessage::getNoteNumber() const noexcept
void MidiMessage::setNoteNumber (const int newNoteNumber) noexcept
{
if (isNoteOnOrOff())
if (isNoteOnOrOff() || isAftertouch())
getData()[1] = (uint8) (newNoteNumber & 127);
}


+ 16
- 5
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp View File

@@ -156,23 +156,34 @@ struct MidiMessageSequenceSorter
}
};
void MidiMessageSequence::addSequence (const MidiMessageSequence& other, double timeAdjustment)
{
for (int i = 0; i < other.list.size(); ++i)
{
const MidiMessage& m = other.list.getUnchecked(i)->message;
MidiEventHolder* const newOne = new MidiEventHolder (m);
newOne->message.addToTimeStamp (timeAdjustment);
list.add (newOne);
}
sort();
}
void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
double timeAdjustment,
double firstAllowableTime,
double endOfAllowableDestTimes)
{
firstAllowableTime -= timeAdjustment;
endOfAllowableDestTimes -= timeAdjustment;
for (int i = 0; i < other.list.size(); ++i)
{
const MidiMessage& m = other.list.getUnchecked(i)->message;
const double t = m.getTimeStamp();
const double t = m.getTimeStamp() + timeAdjustment;
if (t >= firstAllowableTime && t < endOfAllowableDestTimes)
{
MidiEventHolder* const newOne = new MidiEventHolder (m);
newOne->message.setTimeStamp (timeAdjustment + t);
newOne->message.setTimeStamp (t);
list.add (newOne);
}


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

@@ -160,7 +160,6 @@ public:
void deleteEvent (int index, bool deleteMatchingNoteUp);
/** Merges another sequence into this one.
Remember to call updateMatchedPairs() after using this method.
@param other the sequence to add from
@@ -178,6 +177,16 @@ public:
double firstAllowableDestTime,
double endOfAllowableDestTimes);
/** Merges another sequence into this one.
Remember to call updateMatchedPairs() after using this method.
@param other the sequence to add from
@param timeAdjustmentDelta an amount to add to the timestamps of the midi events
as they are read from the other sequence
*/
void addSequence (const MidiMessageSequence& other,
double timeAdjustmentDelta);
//==============================================================================
/** Makes sure all the note-on and note-off pairs are up-to-date.


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp View File

@@ -331,7 +331,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
void expectContainsRPN (const MidiBuffer& midiBuffer,
int channel,
int parameterNumber,
@@ -343,7 +343,7 @@ private:
expectContainsRPN (midiBuffer, expected);
}
//==========================================================================
//==============================================================================
void expectContainsRPN (const MidiBuffer& midiBuffer, MidiRPNMessage expected)
{
MidiBuffer::Iterator iter (midiBuffer);


+ 6
- 6
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiRPN.h View File

@@ -26,7 +26,7 @@
#define JUCE_MIDIRPNDETECTOR_H_INCLUDED
//==========================================================================
//==============================================================================
/** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered
parameter number) message.
*/
@@ -77,7 +77,7 @@ public:
*/
void reset() noexcept;
//==========================================================================
//==============================================================================
/** Takes the next in a stream of incoming MIDI CC messages and returns true
if it forms the last of a sequence that makes an RPN or NPRN.
@@ -91,7 +91,7 @@ public:
MidiRPNMessage& result) noexcept;
private:
//==========================================================================
//==============================================================================
struct ChannelState
{
ChannelState() noexcept;
@@ -104,7 +104,7 @@ private:
bool isNRPN;
};
//==========================================================================
//==============================================================================
ChannelState states[16];
JUCE_LEAK_DETECTOR (MidiRPNDetector)
@@ -120,11 +120,11 @@ private:
class JUCE_API MidiRPNGenerator
{
public:
//==========================================================================
//==============================================================================
/** Generates a MIDI sequence representing the given RPN or NRPN message. */
static MidiBuffer generate (MidiRPNMessage message);
//==========================================================================
//==============================================================================
/** Generates a MIDI sequence representing an RPN or NRPN message with the
given parameters.


+ 5
- 13
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp View File

@@ -135,14 +135,6 @@ void MPEInstrument::removeListener (Listener* const listenerToRemove) noexcept
listeners.remove (listenerToRemove);
}
MPEInstrument::Listener::Listener()
{
}
MPEInstrument::Listener::~Listener()
{
}
//==============================================================================
void MPEInstrument::processNextMidiEvent (const MidiMessage& message)
{
@@ -1976,7 +1968,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
/* This mock class is used for unit testing whether the methods of
MPEInstrument are called correctly.
*/
@@ -2074,7 +2066,7 @@ private:
ScopedPointer<MPENote> lastNoteFinished;
private:
//======================================================================
//==============================================================================
void noteAdded (MPENote) override { noteAddedCallCounter++; }
void notePressureChanged (MPENote) override { notePressureChangedCallCounter++; }
@@ -2089,7 +2081,7 @@ private:
}
};
//==========================================================================
//==============================================================================
template <int initial7BitPressure, int initial14BitPitchbend, int initial7BitTimbre>
class CustomInitialValuesTest : public MPEInstrument
{
@@ -2109,7 +2101,7 @@ private:
}
};
//==========================================================================
//==============================================================================
void expectNote (MPENote noteToTest,
int noteOnVelocity7Bit,
int pressure7Bit,
@@ -2141,7 +2133,7 @@ private:
expect (std::fabs (expected - actual) < maxAbsoluteError);
}
//==========================================================================
//==============================================================================
MPEZoneLayout testLayout;
};


+ 14
- 17
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h View File

@@ -68,7 +68,7 @@ public:
/** Destructor. */
virtual ~MPEInstrument();
//==========================================================================
//==============================================================================
/** Returns the current zone layout of the instrument.
This happens by value, to enforce thread-safety and class invariants.
@@ -98,7 +98,7 @@ public:
*/
bool isMasterChannel (int midiChannel) const noexcept;
//==========================================================================
//==============================================================================
/** The MPE note tracking mode. In case there is more than one note playing
simultaneously on the same MIDI channel, this determines which of these
notes will be modulated by an incoming MPE message on that channel
@@ -123,7 +123,7 @@ public:
/** Set the MPE tracking mode for the timbre dimension. */
void setTimbreTrackingMode (TrackingMode modeToUse);
//==========================================================================
//==============================================================================
/** Process a MIDI message and trigger the appropriate method calls
(noteOn, noteOff etc.)
@@ -132,7 +132,7 @@ public:
*/
virtual void processNextMidiEvent (const MidiMessage& message);
//==========================================================================
//==============================================================================
/** Request a note-on on the given channel, with the given initial note
number and velocity.
If the message arrives on a valid note channel, this will create a
@@ -187,7 +187,7 @@ public:
*/
void releaseAllNotes();
//==========================================================================
//==============================================================================
/** Returns the number of MPE notes currently played by the
instrument.
*/
@@ -221,7 +221,7 @@ public:
*/
MPENote getMostRecentNoteOtherThan (MPENote otherThanThisNote) const noexcept;
//==========================================================================
//==============================================================================
/** Derive from this class to be informed about any changes in the expressive
MIDI notes played by this instrument.
@@ -230,14 +230,11 @@ public:
Therefore you should never do heavy work such as graphics rendering etc.
inside those callbacks.
*/
class Listener
class JUCE_API Listener
{
public:
/** Constructor. */
Listener();
/** Destructor. */
virtual ~Listener();
virtual ~Listener() {}
/** Implement this callback to be informed whenever a new expressive
MIDI note is triggered.
@@ -278,14 +275,14 @@ public:
virtual void noteReleased (MPENote finishedNote) = 0;
};
//==========================================================================
//==============================================================================
/** Adds a listener. */
void addListener (Listener* const listenerToAdd) noexcept;
void addListener (Listener* listenerToAdd) noexcept;
/** Removes a listener. */
void removeListener (Listener* const listenerToRemove) noexcept;
void removeListener (Listener* listenerToRemove) noexcept;
//==========================================================================
//==============================================================================
/** Puts the instrument into legacy mode.
As a side effect, this will discard all currently playing notes,
and call noteReleased for all of them.
@@ -324,7 +321,7 @@ public:
void setLegacyModePitchbendRange (int pitchbendRange);
protected:
//==========================================================================
//==============================================================================
/** This method defines what initial pitchbend value should be used for newly
triggered notes. The default is to use the last pitchbend value
that has been received on the same MIDI channel (or no pitchbend
@@ -354,7 +351,7 @@ protected:
MPEValue midiNoteOnVelocity) const;
private:
//==========================================================================
//==============================================================================
CriticalSection lock;
Array<MPENote> notes;
MPEZoneLayout zoneLayout;


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp View File

@@ -162,7 +162,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
void testMidiBuffer (MidiBuffer& buffer, const uint8* expectedBytes, int expectedBytesSize)
{
uint8 actualBytes[128] = { 0 };
@@ -171,7 +171,7 @@ private:
expectEquals (std::memcmp (actualBytes, expectedBytes, (std::size_t) expectedBytesSize), 0);
}
//==========================================================================
//==============================================================================
void extractRawBinaryData (const MidiBuffer& midiBuffer, const uint8* bufferToCopyTo, std::size_t maxBytes)
{
std::size_t pos = 0;


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp View File

@@ -103,7 +103,7 @@ class MPENoteTests : public UnitTest
public:
MPENoteTests() : UnitTest ("MPENote class") {}
//==========================================================================
//==============================================================================
void runTest() override
{
beginTest ("getFrequencyInHertz");
@@ -116,7 +116,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
void expectEqualsWithinOneCent (double frequencyInHertzActual,
double frequencyInHertzExpected)
{


+ 6
- 6
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPENote.h View File

@@ -39,7 +39,7 @@
*/
struct JUCE_API MPENote
{
//==========================================================================
//==============================================================================
enum KeyState
{
off = 0,
@@ -48,7 +48,7 @@ struct JUCE_API MPENote
keyDownAndSustained = 3
};
//==========================================================================
//==============================================================================
/** Constructor.
@param midiChannel The MIDI channel of the note, between 2 and 16.
@@ -88,7 +88,7 @@ struct JUCE_API MPENote
/** Checks whether the MPE note is valid. */
bool isValid() const noexcept;
//==========================================================================
//==============================================================================
// Invariants that define the note.
/** A unique ID. Useful to distinguish the note from other simultaneously
@@ -107,7 +107,7 @@ struct JUCE_API MPENote
*/
uint8 initialNote;
//==========================================================================
//==============================================================================
// The five dimensions of continuous expressive control
/** The velocity ("strike") of the note-on.
@@ -146,7 +146,7 @@ struct JUCE_API MPENote
*/
MPEValue noteOffVelocity;
//==========================================================================
//==============================================================================
/** Current effective pitchbend of the note in units of semitones, relative
to initialNote. You should use this to compute the actual effective pitch
of the note. This value is computed and set by an MPEInstrument to the
@@ -163,7 +163,7 @@ struct JUCE_API MPENote
*/
KeyState keyState;
//==========================================================================
//==============================================================================
/** Returns the current frequency of the note in Hertz. This is the a sum of
the initialNote and the totalPitchbendInSemitones, converted to Hertz.
*/


+ 9
- 9
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h View File

@@ -55,7 +55,7 @@
class JUCE_API MPESynthesiser : public MPESynthesiserBase
{
public:
//==========================================================================
//==============================================================================
/** Constructor.
You'll need to add some voices before it'll make any sound.
@@ -75,7 +75,7 @@ public:
/** Destructor. */
~MPESynthesiser();
//==========================================================================
//==============================================================================
/** Deletes all voices. */
void clearVoices();
@@ -116,7 +116,7 @@ public:
*/
virtual void turnOffAllVoices (bool allowTailOff);
//==========================================================================
//==============================================================================
/** If set to true, then the synth will try to take over an existing voice if
it runs out and needs to play another note.
@@ -128,7 +128,7 @@ public:
/** Returns true if note-stealing is enabled. */
bool isVoiceStealingEnabled() const noexcept { return shouldStealVoices; }
//==========================================================================
//==============================================================================
/** Tells the synthesiser what the sample rate is for the audio it's being used to render.
This overrides the implementation in MPESynthesiserBase, to additionally
@@ -137,7 +137,7 @@ public:
*/
void setCurrentPlaybackSampleRate (double newRate) override;
//==========================================================================
//==============================================================================
/** Handle incoming MIDI events.
This method will be called automatically according to the MIDI data passed
@@ -238,7 +238,7 @@ protected:
*/
virtual void noteKeyStateChanged (MPENote changedNote) override;
//==========================================================================
//==============================================================================
/** This will simply call renderNextBlock for each currently active
voice and fill the buffer with the sum.
Override this method if you need to do more work to render your audio.
@@ -255,7 +255,7 @@ protected:
int startSample,
int numSamples) override;
//==========================================================================
//==============================================================================
/** Searches through the voices to find one that's not currently playing, and
which can play the given MPE note.
@@ -298,11 +298,11 @@ protected:
*/
void stopVoice (MPESynthesiserVoice* voice, MPENote noteToStop, bool allowTailOff);
//==========================================================================
//==============================================================================
OwnedArray<MPESynthesiserVoice> voices;
private:
//==========================================================================
//==============================================================================
bool shouldStealVoices;
CriticalSection voicesLock;


+ 10
- 10
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h View File

@@ -47,7 +47,7 @@
struct JUCE_API MPESynthesiserBase : public MPEInstrument::Listener
{
public:
//==========================================================================
//==============================================================================
/** Constructor. */
MPESynthesiserBase();
@@ -61,7 +61,7 @@ public:
*/
MPESynthesiserBase (MPEInstrument* instrument);
//==========================================================================
//==============================================================================
/** Returns the synthesiser's internal MPE zone layout.
This happens by value, to enforce thread-safety and class invariants.
*/
@@ -73,7 +73,7 @@ public:
*/
void setZoneLayout (MPEZoneLayout newLayout);
//==========================================================================
//==============================================================================
/** Tells the synthesiser what the sample rate is for the audio it's being
used to render.
*/
@@ -84,7 +84,7 @@ public:
*/
double getSampleRate() const noexcept { return sampleRate; }
//==========================================================================
//==============================================================================
/** Creates the next block of audio output.
Call this to make sound. This will chop up the AudioBuffer into subBlock
@@ -99,7 +99,7 @@ public:
int startSample,
int numSamples);
//==========================================================================
//==============================================================================
/** Handle incoming MIDI events (called from renderNextBlock).
The default implementation provided here simply forwards everything
@@ -113,7 +113,7 @@ public:
*/
virtual void handleMidiEvent (const MidiMessage&);
//==========================================================================
//==============================================================================
/** Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering.
When rendering, the audio blocks that are passed into renderNextBlock() will be split up
@@ -130,7 +130,7 @@ public:
*/
void setMinimumRenderingSubdivisionSize (int numSamples) noexcept;
//==========================================================================
//==============================================================================
/** Puts the synthesiser into legacy mode.
@param pitchbendRange The note pitchbend range in semitones to use when in legacy mode.
@@ -160,7 +160,7 @@ public:
void setLegacyModePitchbendRange (int pitchbendRange);
protected:
//==========================================================================
//==============================================================================
/** Implement this method to render your audio inside.
@see renderNextBlock
*/
@@ -176,14 +176,14 @@ protected:
int /*numSamples*/) {}
protected:
//==========================================================================
//==============================================================================
/** @internal */
ScopedPointer<MPEInstrument> instrument;
/** @internal */
CriticalSection renderAudioLock;
private:
//==========================================================================
//==============================================================================
double sampleRate;
int minimumSubBlockSize;


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

@@ -37,7 +37,7 @@
class JUCE_API MPESynthesiserVoice
{
public:
//========================================================================
//==============================================================================
/** Constructor. */
MPESynthesiserVoice();
@@ -160,7 +160,7 @@ public:
bool wasStartedBefore (const MPESynthesiserVoice& other) const noexcept;
protected:
//==========================================================================
//==============================================================================
/** Resets the state of this voice after a sound has finished playing.
The subclass must call this when it finishes playing a note and becomes available
@@ -175,12 +175,12 @@ protected:
*/
void clearCurrentNote() noexcept;
//==========================================================================
//==============================================================================
double currentSampleRate;
MPENote currentlyPlayingNote;
private:
//==========================================================================
//==============================================================================
friend class MPESynthesiser;
uint32 noteStartTime;


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp View File

@@ -144,7 +144,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
void expectValuesConsistent (MPEValue value,
int expectedValueAs7BitInt,
int expectedValueAs14BitInt,
@@ -157,7 +157,7 @@ private:
expectFloatWithinRelativeError (value.asUnsignedFloat(), expectedValueAsUnsignedFloat, 0.0001f);
}
//==========================================================================
//==============================================================================
void expectFloatWithinRelativeError (float actualValue, float expectedValue, float maxRelativeError)
{
const float maxAbsoluteError = jmax (1.0f, std::fabs (expectedValue)) * maxRelativeError;


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEValue.h View File

@@ -37,7 +37,7 @@
class JUCE_API MPEValue
{
public:
//==========================================================================
//==============================================================================
/** Default constructor. Constructs an MPEValue corresponding
to the centre value.
*/
@@ -87,7 +87,7 @@ public:
bool operator!= (const MPEValue& other) const noexcept;
private:
//==========================================================================
//==============================================================================
MPEValue (int normalisedValue);
int normalisedValue;
};


+ 3
- 3
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp View File

@@ -144,7 +144,7 @@ bool MPEZone::truncateToFit (MPEZone other) noexcept
return true;
}
//==========================================================================
//==============================================================================
bool MPEZone::operator== (const MPEZone& other) const noexcept
{
return masterChannel == other.masterChannel
@@ -284,7 +284,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
void testOverlapsWith (int masterChannelFirst, int numNoteChannelsFirst,
int masterChannelSecond, int numNoteChannelsSecond,
bool expectedRetVal)
@@ -296,7 +296,7 @@ private:
expect (second.overlapsWith (first) == expectedRetVal);
}
//==========================================================================
//==============================================================================
void testTruncateToFit (int masterChannelFirst, int numNoteChannelsFirst,
int masterChannelSecond, int numNoteChannelsSecond,
bool expectedRetVal,


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

@@ -127,7 +127,7 @@ struct JUCE_API MPEZone
bool operator!= (const MPEZone& other) const noexcept;
private:
//==========================================================================
//==============================================================================
int masterChannel;
int numNoteChannels;
int perNotePitchbendRange;


+ 0
- 8
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp View File

@@ -197,14 +197,6 @@ void MPEZoneLayout::removeListener (Listener* const listenerToRemove) noexcept
listeners.remove (listenerToRemove);
}
MPEZoneLayout::Listener::Listener()
{
}
MPEZoneLayout::Listener::~Listener()
{
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS


+ 4
- 7
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h View File

@@ -125,18 +125,15 @@ public:
*/
MPEZone* getZoneByNoteChannel (int midiChannel) const noexcept;
//==========================================================================
//==============================================================================
/** Listener class. Derive from this class to allow your class to be
notified about changes to the zone layout.
*/
class Listener
{
public:
/** Constructor. */
Listener();
/** Destructor. */
virtual ~Listener();
virtual ~Listener() {}
/** Implement this callback to be notified about any changes to this
MPEZoneLayout. Will be called whenever a zone is added, zones are
@@ -145,7 +142,7 @@ public:
virtual void zoneLayoutChanged (const MPEZoneLayout& layout) = 0;
};
//==========================================================================
//==============================================================================
/** Adds a listener. */
void addListener (Listener* const listenerToAdd) noexcept;
@@ -153,7 +150,7 @@ public:
void removeListener (Listener* const listenerToRemove) noexcept;
private:
//==========================================================================
//==============================================================================
Array<MPEZone> zones;
MidiRPNDetector rpnDetector;
ListenerList<Listener> listeners;


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

@@ -46,7 +46,7 @@ public:
@param source the input source to read from
@param backgroundThread a background thread that will be used for the
background read-ahead. This object must not be deleted
until after any BufferedAudioSources that are using it
until after any BufferingAudioSources that are using it
have been deleted!
@param deleteSourceWhenDeleted if true, then the input source object will
be deleted when this object is deleted


+ 11
- 8
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -993,9 +993,9 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
class AudioSampleBufferSource : public PositionableAudioSource
{
public:
AudioSampleBufferSource (AudioSampleBuffer* audioBuffer, bool ownBuffer)
AudioSampleBufferSource (AudioSampleBuffer* audioBuffer, bool ownBuffer, bool playOnAllChannels)
: buffer (audioBuffer, ownBuffer),
position (0), looping (false)
position (0), looping (false), playAcrossAllChannels (playOnAllChannels)
{}
//==============================================================================
@@ -1029,8 +1029,11 @@ public:
if (samplesToCopy > 0)
{
const int maxInChannels = buffer->getNumChannels();
const int maxOutChannels = jmin (bufferToFill.buffer->getNumChannels(), jmax (maxInChannels, 2));
int maxInChannels = buffer->getNumChannels();
int maxOutChannels = bufferToFill.buffer->getNumChannels();
if (! playAcrossAllChannels)
maxOutChannels = jmin (maxOutChannels, maxInChannels);
for (int i = 0; i < maxOutChannels; ++i)
bufferToFill.buffer->copyFrom (i, bufferToFill.startSample, *buffer,
@@ -1047,7 +1050,7 @@ private:
//==============================================================================
OptionalScopedPointer<AudioSampleBuffer> buffer;
int position;
bool looping;
bool looping, playAcrossAllChannels;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSampleBufferSource)
};
@@ -1080,10 +1083,10 @@ void AudioDeviceManager::playSound (AudioFormatReader* reader, bool deleteWhenFi
playSound (new AudioFormatReaderSource (reader, deleteWhenFinished), true);
}
void AudioDeviceManager::playSound (AudioSampleBuffer* buffer, bool deleteWhenFinished)
void AudioDeviceManager::playSound (AudioSampleBuffer* buffer, bool deleteWhenFinished, bool playOnAllOutputChannels)
{
if (buffer != nullptr)
playSound (new AudioSampleBufferSource (buffer, deleteWhenFinished), true);
playSound (new AudioSampleBufferSource (buffer, deleteWhenFinished, playOnAllOutputChannels), true);
}
void AudioDeviceManager::playSound (PositionableAudioSource* audioSource, bool deleteWhenFinished)
@@ -1134,7 +1137,7 @@ void AudioDeviceManager::playTestSound()
newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
playSound (newSound, true);
playSound (newSound, true, true);
}
//==============================================================================


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

@@ -445,8 +445,15 @@ public:
This will output the sound contained in an audio sample buffer. If
deleteWhenFinished is true then the audio sample buffer will be
automatically deleted once the sound has finished playing.
If playOnAllOutputChannels is true, then if there are more output channels
than buffer channels, then the ones that are available will be re-used on
multiple outputs so that something is sent to all output channels. If it
is false, then the buffer will just be played on the first output channels.
*/
void playSound (AudioSampleBuffer* buffer, bool deleteWhenFinished = false);
void playSound (AudioSampleBuffer* buffer,
bool deleteWhenFinished = false,
bool playOnAllOutputChannels = false);
//==============================================================================
/** Turns on level-measuring.


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

@@ -31,7 +31,12 @@
#error "Incorrect use of JUCE cpp file"
#endif
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
#define JUCE_CORE_INCLUDE_COM_SMART_PTR 1
#define JUCE_CORE_INCLUDE_JNI_HELPERS 1
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1
#include "juce_audio_devices.h"
//==============================================================================
@@ -141,7 +146,6 @@ namespace juce
//==============================================================================
#if JUCE_MAC
#include "../juce_core/native/juce_osx_ObjCHelpers.h"
#include "native/juce_mac_CoreAudio.cpp"
#include "native/juce_mac_CoreMidi.cpp"
@@ -160,8 +164,6 @@ namespace juce
//==============================================================================
#elif JUCE_WINDOWS
#include "../juce_core/native/juce_win32_ComSmartPtr.h"
#include "../juce_events/native/juce_win32_HiddenMessageWindow.h"
#if JUCE_WASAPI
#include "native/juce_win32_WASAPI.cpp"
@@ -203,7 +205,6 @@ namespace juce
//==============================================================================
#elif JUCE_ANDROID
#include "../juce_core/native/juce_android_JNIHelpers.h"
#include "native/juce_android_Audio.cpp"
#include "native/juce_android_Midi.cpp"


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

@@ -29,7 +29,7 @@
#include "../juce_audio_basics/juce_audio_basics.h"
#include "../juce_audio_formats/juce_audio_formats.h"
//=============================================================================
//==============================================================================
/** Config: JUCE_ASIO
Enables ASIO audio devices (MS Windows only).
Turning this on means that you'll need to have the Steinberg ASIO SDK installed
@@ -90,7 +90,7 @@
#endif
#endif
//=============================================================================
//==============================================================================
/** Config: JUCE_USE_CDREADER
Enables the AudioCDReader class (on supported platforms).
*/
@@ -105,7 +105,7 @@
#define JUCE_USE_CDBURNER 0
#endif
//=============================================================================
//==============================================================================
namespace juce
{


+ 39
- 13
libs/juce/source/modules/juce_audio_devices/native/juce_android_Audio.cpp View File

@@ -195,25 +195,51 @@ public:
STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT,
(jint) (minBufferSizeOut * numDeviceOutputChannels * sizeof (int16)), MODE_STREAM));
if (env->CallIntMethod (outputDevice, AudioTrack.getState) != STATE_UNINITIALIZED)
int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState);
if (outputDeviceState > 0)
{
isRunning = true;
}
else
outputDevice.clear(); // failed to open the device
{
// failed to open the device
outputDevice.clear();
lastError = "Error opening audio output device: android.media.AudioTrack failed with state = " + String (outputDeviceState);
}
}
if (numClientInputChannels > 0 && numDeviceInputChannelsAvailable > 0)
{
numDeviceInputChannels = jmin (numClientInputChannels, numDeviceInputChannelsAvailable);
inputDevice = GlobalRef (env->NewObject (AudioRecord, AudioRecord.constructor,
0 /* (default audio source) */, sampleRate,
numDeviceInputChannelsAvailable > 1 ? CHANNEL_IN_STEREO : CHANNEL_IN_MONO,
ENCODING_PCM_16BIT,
(jint) (minBufferSizeIn * numDeviceInputChannels * sizeof (int16))));
if (env->CallIntMethod (inputDevice, AudioRecord.getState) != STATE_UNINITIALIZED)
isRunning = true;
if (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))
{
// If you hit this assert, you probably forgot to get RuntimePermissions::recordAudio
// before trying to open an audio input device. This is not going to work!
jassertfalse;
inputDevice.clear();
lastError = "Error opening audio input device: the app was not granted android.permission.RECORD_AUDIO";
}
else
inputDevice.clear(); // failed to open the device
{
numDeviceInputChannels = jmin (numClientInputChannels, numDeviceInputChannelsAvailable);
inputDevice = GlobalRef (env->NewObject (AudioRecord, AudioRecord.constructor,
0 /* (default audio source) */, sampleRate,
numDeviceInputChannelsAvailable > 1 ? CHANNEL_IN_STEREO : CHANNEL_IN_MONO,
ENCODING_PCM_16BIT,
(jint) (minBufferSizeIn * numDeviceInputChannels * sizeof (int16))));
int inputDeviceState = env->CallIntMethod (inputDevice, AudioRecord.getState);
if (inputDeviceState > 0)
{
isRunning = true;
}
else
{
// failed to open the device
inputDevice.clear();
lastError = "Error opening audio input device: android.media.AudioRecord failed with state = " + String (inputDeviceState);
}
}
}
if (isRunning)
@@ -368,7 +394,7 @@ public:
int minBufferSizeOut, minBufferSizeIn;
private:
//==================================================================================================
//==============================================================================
CriticalSection callbackLock;
AudioIODeviceCallback* callback;
jint sampleRate;


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

@@ -145,12 +145,32 @@ public:
<< ", sampleRate = " << sampleRate);
if (numInputChannels > 0)
recorder = engine.createRecorder (numInputChannels, sampleRate,
audioBuffersToEnqueue, actualBufferSize);
{
if (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))
{
// If you hit this assert, you probably forgot to get RuntimePermissions::recordAudio
// before trying to open an audio input device. This is not going to work!
jassertfalse;
lastError = "Error opening OpenSL input device: the app was not granted android.permission.RECORD_AUDIO";
}
else
{
recorder = engine.createRecorder (numInputChannels, sampleRate,
audioBuffersToEnqueue, actualBufferSize);
if (recorder == nullptr)
lastError = "Error opening OpenSL input device: creating Recorder failed.";
}
}
if (numOutputChannels > 0)
player = engine.createPlayer (numOutputChannels, sampleRate,
audioBuffersToEnqueue, actualBufferSize);
{
player = engine.createPlayer (numOutputChannels, sampleRate,
audioBuffersToEnqueue, actualBufferSize);
if (player == nullptr)
lastError = "Error opening OpenSL input device: creating Player failed.";
}
// pre-fill buffers
for (int i = 0; i < audioBuffersToEnqueue; ++i)
@@ -220,7 +240,7 @@ public:
}
private:
//==================================================================================================
//==============================================================================
CriticalSection callbackLock;
AudioIODeviceCallback* callback;
int actualBufferSize, sampleRate;
@@ -242,7 +262,7 @@ private:
defaultBufferSizeIsMultipleOfNative = 1
};
//==================================================================================================
//==============================================================================
static String audioManagerGetProperty (const String& property)
{
const LocalRef<jstring> jProperty (javaString (property));
@@ -281,7 +301,7 @@ private:
return androidHasSystemFeature ("android.hardware.audio.low_latency");
}
//==================================================================================================
//==============================================================================
AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback)
{
const ScopedLock sl (callbackLock);
@@ -331,7 +351,7 @@ private:
DBG ("Unable to set audio thread priority: priority is still " << priority);
}
//==================================================================================================
//==============================================================================
struct Engine
{
Engine()
@@ -400,7 +420,7 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Engine)
};
//==================================================================================================
//==============================================================================
struct BufferList
{
BufferList (const int numChannels_, const int numBuffers_, const int numSamples_)
@@ -444,7 +464,7 @@ private:
WaitableEvent dataArrived;
};
//==================================================================================================
//==============================================================================
struct Player
{
Player (int numChannels, int sampleRate, Engine& engine, int playerNumBuffers, int playerBufferSize)
@@ -559,7 +579,7 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Player)
};
//==================================================================================================
//==============================================================================
struct Recorder
{
Recorder (int numChannels, int sampleRate, Engine& engine, const int numBuffers, const int numSamples)


+ 27
- 22
libs/juce/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp View File

@@ -24,7 +24,9 @@
class iOSAudioIODevice;
//==================================================================================================
static const char* const iOSAudioDeviceName = "iOS Audio";
//==============================================================================
struct AudioSessionHolder
{
AudioSessionHolder();
@@ -74,7 +76,7 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS
} // juce namespace
//==================================================================================================
//==============================================================================
@interface iOSAudioSessionNative : NSObject
{
@private
@@ -178,7 +180,7 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS
@end
//==================================================================================================
//==============================================================================
namespace juce {
#ifndef JUCE_IOS_AUDIO_LOGGING
@@ -203,11 +205,12 @@ static void logNSError (NSError* e)
#define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); }
//==================================================================================================
//==============================================================================
class iOSAudioIODevice : public AudioIODevice
{
public:
iOSAudioIODevice (const String& deviceName) : AudioIODevice (deviceName, "Audio")
iOSAudioIODevice (const String& deviceName)
: AudioIODevice (deviceName, iOSAudioDeviceName)
{
sessionHolder->activeDevices.add (this);
updateSampleRateAndAudioInput();
@@ -350,13 +353,14 @@ public:
{
isRunning = false;
setAudioSessionActive (false);
if (audioUnit != 0)
{
AudioOutputUnitStart (audioUnit);
AudioComponentInstanceDispose (audioUnit);
audioUnit = 0;
}
setAudioSessionActive (false);
}
}
@@ -463,13 +467,13 @@ public:
AudioOutputUnitStart (audioUnit);
}
if (callback)
if (callback != nullptr)
callback->audioDeviceAboutToStart (this);
}
}
private:
//==================================================================================================
//==============================================================================
SharedResourcePointer<AudioSessionHolder> sessionHolder;
CriticalSection callbackLock;
NSTimeInterval sampleRate = 0;
@@ -505,7 +509,7 @@ private:
}
}
//==================================================================================================
//==============================================================================
OSStatus process (AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time,
const UInt32 numFrames, AudioBufferList* data)
{
@@ -592,21 +596,22 @@ private:
auto session = [AVAudioSession sharedInstance];
sampleRate = session.sampleRate;
audioInputIsAvailable = session.isInputAvailable;
JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate << "Hz, audioInputAvailable: " << (int) audioInputIsAvailable);
actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration);
JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate
<< "Hz, audioInputAvailable: " << (int) audioInputIsAvailable);
}
void updateCurrentBufferSize()
{
auto session = [AVAudioSession sharedInstance];
NSTimeInterval bufferDuration = sampleRate > 0 ? (NSTimeInterval) (preferredBufferSize / sampleRate) : 0.0;
JUCE_NSERROR_CHECK ([session setPreferredIOBufferDuration: bufferDuration
error: &error]);
NSTimeInterval bufferDuration = sampleRate > 0 ? (NSTimeInterval) ((preferredBufferSize + 1) / sampleRate) : 0.0;
bufferDuration = session.IOBufferDuration;
actualBufferSize = roundToInt (sampleRate * bufferDuration);
JUCE_NSERROR_CHECK ([[AVAudioSession sharedInstance] setPreferredIOBufferDuration: bufferDuration
error: &error]);
updateSampleRateAndAudioInput();
}
//==================================================================================================
//==============================================================================
static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time,
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data)
{
@@ -614,7 +619,7 @@ private:
return static_cast<iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
}
//==================================================================================================
//==============================================================================
void resetFormat (const int numChannels) noexcept
{
zerostruct (format);
@@ -712,10 +717,10 @@ private:
class iOSAudioIODeviceType : public AudioIODeviceType
{
public:
iOSAudioIODeviceType() : AudioIODeviceType ("iOS Audio") {}
iOSAudioIODeviceType() : AudioIODeviceType (iOSAudioDeviceName) {}
void scanForDevices() {}
StringArray getDeviceNames (bool /*wantInputNames*/) const { return StringArray ("iOS Audio"); }
StringArray getDeviceNames (bool /*wantInputNames*/) const { return StringArray (iOSAudioDeviceName); }
int getDefaultDeviceIndex (bool /*forInput*/) const { return 0; }
int getIndexOfDevice (AudioIODevice* d, bool /*asInput*/) const { return d != nullptr ? 0 : -1; }
bool hasSeparateInputsAndOutputs() const { return false; }
@@ -738,7 +743,7 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio()
return new iOSAudioIODeviceType();
}
//==================================================================================================
//==============================================================================
AudioSessionHolder::AudioSessionHolder() { nativeSession = [[iOSAudioSessionNative alloc] init: this]; }
AudioSessionHolder::~AudioSessionHolder() { [nativeSession release]; }


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

@@ -31,6 +31,12 @@
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull" // aovid some spurious 10.11 SDK warnings
// The AudioHardwareService stuff was deprecated in 10.11 but there's no replacement yet,
// so we'll have to silence the warnings here and revisit it in a future OS version..
#if defined (MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_11
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
#endif
//==============================================================================
@@ -382,65 +388,84 @@ public:
return 0;
}
void updateDetailsFromDevice()
int getFrameSizeFromDevice() const
{
stopTimer();
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
if (deviceID == 0)
return;
UInt32 framesPerBuf = (UInt32) bufferSize;
UInt32 size = sizeof (framesPerBuf);
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf);
return (int) framesPerBuf;
}
// this collects all the new details from the device without any locking, then
// locks + swaps them afterwards.
bool isDeviceAlive() const
{
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
UInt32 isAlive;
UInt32 isAlive = 0;
UInt32 size = sizeof (isAlive);
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive)) && isAlive == 0)
return;
return deviceID != 0
&& OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive))
&& isAlive != 0;
}
const double currentRate = getNominalSampleRate();
if (currentRate > 0)
sampleRate = currentRate;
bool updateDetailsFromDevice()
{
stopTimer();
UInt32 framesPerBuf = (UInt32) bufferSize;
size = sizeof (framesPerBuf);
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf);
if (! isDeviceAlive())
return false;
// this collects all the new details from the device without any locking, then
// locks + swaps them afterwards.
Array<int> newBufferSizes (getBufferSizesFromDevice());
Array<double> newSampleRates (getSampleRatesFromDevice());
const double newSampleRate = getNominalSampleRate();
const int newBufferSize = getFrameSizeFromDevice();
inputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput);
outputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput);
Array<int> newBufferSizes = getBufferSizesFromDevice();
Array<double> newSampleRates = getSampleRatesFromDevice();
const int newInputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput);
const int newOutputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput);
Array<CallbackDetailsForChannel> newInChans, newOutChans;
StringArray newInNames (getChannelInfo (true, newInChans));
StringArray newOutNames (getChannelInfo (false, newOutChans));
const int inputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeInput);
const int outputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeOutput);
const int newBitDepth = jmax (getBitDepthFromDevice (kAudioDevicePropertyScopeInput),
getBitDepthFromDevice (kAudioDevicePropertyScopeOutput));
{
const ScopedLock sl (callbackLock);
bitDepth = jmax (inputBitDepth, outputBitDepth);
if (bitDepth <= 0)
bitDepth = 32;
bitDepth = newBitDepth > 0 ? newBitDepth : 32;
// after getting the new values, lock + apply them
const ScopedLock sl (callbackLock);
if (newSampleRate > 0)
sampleRate = newSampleRate;
bufferSize = (int) framesPerBuf;
allocateTempBuffers();
inputLatency = newInputLatency;
outputLatency = newOutputLatency;
bufferSize = newBufferSize;
sampleRates.swapWith (newSampleRates);
bufferSizes.swapWith (newBufferSizes);
sampleRates.swapWith (newSampleRates);
bufferSizes.swapWith (newBufferSizes);
inChanNames.swapWith (newInNames);
outChanNames.swapWith (newOutNames);
inChanNames.swapWith (newInNames);
outChanNames.swapWith (newOutNames);
inputChannelInfo.swapWith (newInChans);
outputChannelInfo.swapWith (newOutChans);
inputChannelInfo.swapWith (newInChans);
outputChannelInfo.swapWith (newOutChans);
allocateTempBuffers();
}
return true;
}
//==============================================================================
@@ -763,9 +788,10 @@ public:
stopTimer();
const double oldSampleRate = sampleRate;
const int oldBufferSize = bufferSize;
updateDetailsFromDevice();
if (oldBufferSize != bufferSize || oldSampleRate != sampleRate)
if (! updateDetailsFromDevice())
owner.stop();
else if (oldBufferSize != bufferSize || oldSampleRate != sampleRate)
owner.restart();
}


+ 36
- 27
libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -320,9 +320,9 @@ public:
classId (clsID),
inputLatency (0),
outputLatency (0),
minSize (0), maxSize (0),
preferredSize (0),
granularity (0),
minBufferSize (0), maxBufferSize (0),
preferredBufferSize (0),
bufferGranularity (0),
numClockSources (0),
currentBlockSizeSamples (0),
currentBitDepth (16),
@@ -403,7 +403,7 @@ public:
Array<double> getAvailableSampleRates() override { return sampleRates; }
Array<int> getAvailableBufferSizes() override { return bufferSizes; }
int getDefaultBufferSize() override { return preferredSize; }
int getDefaultBufferSize() override { return preferredBufferSize; }
String open (const BigInteger& inputChannels,
const BigInteger& outputChannels,
@@ -469,10 +469,10 @@ public:
removeCurrentDriver();
loadDriver();
const String error (initDriver());
String initError = initDriver();
if (error.isNotEmpty())
JUCE_ASIO_LOG ("ASIOInit: " + error);
if (initError.isNotEmpty())
JUCE_ASIO_LOG ("ASIOInit: " + initError);
needToReset = false;
}
@@ -489,7 +489,7 @@ public:
if (err != ASE_OK)
{
currentBlockSizeSamples = preferredSize;
currentBlockSizeSamples = preferredBufferSize;
JUCE_ASIO_LOG_ERROR ("create buffers 2", err);
asioObject->disposeBuffers();
@@ -561,8 +561,7 @@ public:
}
readLatencies();
asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity);
refreshBufferSizes();
deviceIsOpen = true;
JUCE_ASIO_LOG ("starting");
@@ -762,7 +761,7 @@ private:
Array<double> sampleRates;
Array<int> bufferSizes;
long inputLatency, outputLatency;
long minSize, maxSize, preferredSize, granularity;
long minBufferSize, maxBufferSize, preferredBufferSize, bufferGranularity;
ASIOClockSource clocks[32];
int numClockSources;
@@ -829,23 +828,27 @@ private:
}
}
int readBufferSizes (int bufferSizeSamples)
long refreshBufferSizes()
{
minSize = 0;
maxSize = 0;
granularity = 0;
return asioObject->getBufferSize (&minBufferSize, &maxBufferSize, &preferredBufferSize, &bufferGranularity);
}
int readBufferSizes (int bufferSizeSamples)
{
minBufferSize = 0;
maxBufferSize = 0;
bufferGranularity = 0;
long newPreferredSize = 0;
if (asioObject->getBufferSize (&minSize, &maxSize, &newPreferredSize, &granularity) == ASE_OK)
if (asioObject->getBufferSize (&minBufferSize, &maxBufferSize, &newPreferredSize, &bufferGranularity) == ASE_OK)
{
if (preferredSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredSize)
if (preferredBufferSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredBufferSize)
shouldUsePreferredSize = true;
if (bufferSizeSamples < minSize || bufferSizeSamples > maxSize)
if (bufferSizeSamples < minBufferSize || bufferSizeSamples > maxBufferSize)
shouldUsePreferredSize = true;
preferredSize = newPreferredSize;
preferredBufferSize = newPreferredSize;
}
// unfortunate workaround for certain drivers which crash if you make
@@ -855,11 +858,11 @@ private:
if (shouldUsePreferredSize)
{
JUCE_ASIO_LOG ("Using preferred size for buffer..");
long err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity);
long err = refreshBufferSizes();
if (err == ASE_OK)
{
bufferSizeSamples = (int) preferredSize;
bufferSizeSamples = (int) preferredBufferSize;
}
else
{
@@ -1082,8 +1085,8 @@ private:
if (i < 2)
{
// clear the channels that are used with the dummy stuff
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[0], preferredSize);
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[1], preferredSize);
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[0], preferredBufferSize);
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[1], preferredBufferSize);
}
}
}
@@ -1203,9 +1206,9 @@ private:
inputFormat.calloc (chansToAllocate);
outputFormat.calloc (chansToAllocate);
if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == 0)
if ((err = refreshBufferSizes()) == 0)
{
addBufferSizes (minSize, maxSize, preferredSize, granularity);
addBufferSizes (minBufferSize, maxBufferSize, preferredBufferSize, bufferGranularity);
double currentRate = getSampleRate();
@@ -1226,8 +1229,8 @@ private:
updateSampleRates();
readLatencies(); // ..doing these steps because cubase does so at this stage
createDummyBuffers (preferredSize); // in initialisation, and some devices fail if we don't.
readLatencies(); // ..doing these steps because cubase does so at this stage
createDummyBuffers (preferredBufferSize); // in initialisation, and some devices fail if we don't.
readLatencies();
// start and stop because cubase does it..
@@ -1419,6 +1422,12 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODevice)
};
template <>
struct ASIOAudioIODevice::ASIOCallbackFunctions <sizeof(currentASIODev) / sizeof(currentASIODev[0])>
{
static void setCallbacksForDevice (ASIOCallbacks&, ASIOAudioIODevice*) noexcept {}
};
//==============================================================================
class ASIOAudioIODeviceType : public AudioIODeviceType
{


+ 5
- 0
libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp View File

@@ -112,6 +112,11 @@ bool check (HRESULT hr)
#define JUCE_COMCLASS(name, guid) struct __declspec (uuid (guid)) name
#endif
#if JUCE_MINGW && defined (KSDATAFORMAT_SUBTYPE_PCM)
#undef KSDATAFORMAT_SUBTYPE_PCM
#undef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#endif
#ifndef KSDATAFORMAT_SUBTYPE_PCM
#define KSDATAFORMAT_SUBTYPE_PCM uuidFromString ("00000001-0000-0010-8000-00aa00389b71")
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT uuidFromString ("00000003-0000-0010-8000-00aa00389b71")


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

@@ -33,7 +33,7 @@
#ifndef FLAC__PRIVATE__METADATA_H
#define FLAC__PRIVATE__METADATA_H
#include "FLAC/metadata.h"
#include "../../../metadata.h"
/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not
* be a consistent state (e.g. PICTURE) or equivalent to the initial


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

@@ -112,19 +112,28 @@ struct CoreAudioFormatMetatdata
};
//==============================================================================
struct UserDefinedChunk
static StringPairArray parseUserDefinedChunk (InputStream& input, int64 size)
{
UserDefinedChunk (InputStream& input, int64 size)
StringPairArray infoStrings;
const int64 originalPosition = input.getPosition();
uint8 uuid[16];
input.read (uuid, sizeof (uuid));
if (memcmp (uuid, "\x29\x81\x92\x73\xB5\xBF\x4A\xEF\xB7\x8D\x62\xD1\xEF\x90\xBB\x2C", 16) == 0)
{
// a user defined chunk contains 16 bytes of a UUID first
uuid[1] = input.readInt64BigEndian();
uuid[0] = input.readInt64BigEndian();
const uint32 numEntries = (uint32) input.readIntBigEndian();
input.skipNextBytes (size - 16);
for (uint32 i = 0; i < numEntries && input.getPosition() < originalPosition + size; ++i)
{
String keyName = input.readString();
infoStrings.set (keyName, input.readString());
}
}
int64 uuid[2];
};
input.setPosition (originalPosition + size);
return infoStrings;
}
//==============================================================================
static StringPairArray parseMidiChunk (InputStream& input, int64 size)
@@ -288,7 +297,7 @@ struct CoreAudioFormatMetatdata
}
else if (chunkHeader.chunkType == chunkName ("uuid"))
{
UserDefinedChunk userDefinedChunk (input, chunkHeader.chunkSize);
metadataValues.addArray (parseUserDefinedChunk (input, chunkHeader.chunkSize));
}
else if (chunkHeader.chunkType == chunkName ("data"))
{


+ 0
- 4
libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp View File

@@ -27,15 +27,11 @@
} // (juce namespace)
#if ! JUCE_WINDOWS
#define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers)
#define Component CarbonDummyCompName
#include <QuickTime/Movies.h>
#include <QuickTime/QTML.h>
#include <QuickTime/QuickTimeComponents.h>
#include <QuickTime/MediaHandlers.h>
#include <QuickTime/ImageCodec.h>
#undef Point
#undef Component
#else
#if JUCE_MSVC
#pragma warning (push)


+ 4
- 10
libs/juce/source/modules/juce_audio_formats/juce_audio_formats.cpp View File

@@ -31,19 +31,18 @@
#error "Incorrect use of JUCE cpp file"
#endif
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#define JUCE_CORE_INCLUDE_COM_SMART_PTR 1
#define JUCE_CORE_INCLUDE_JNI_HELPERS 1
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#include "juce_audio_formats.h"
//==============================================================================
#if JUCE_MAC
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#if JUCE_QUICKTIME
#import <QTKit/QTKit.h>
#endif
#include <AudioToolbox/AudioToolbox.h>
#undef Component
#undef Point
#elif JUCE_IOS
#import <AudioToolbox/AudioToolbox.h>
@@ -85,14 +84,9 @@ namespace juce
{
#if JUCE_ANDROID
#include "../juce_core/native/juce_android_JNIHelpers.h"
#undef JUCE_QUICKTIME
#endif
#if JUCE_WINDOWS
#include "../juce_core/native/juce_win32_ComSmartPtr.h"
#endif
#include "format/juce_AudioFormat.cpp"
#include "format/juce_AudioFormatManager.cpp"
#include "format/juce_AudioFormatReader.cpp"


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

@@ -27,7 +27,7 @@
#include "../juce_audio_basics/juce_audio_basics.h"
//=============================================================================
//==============================================================================
/** Config: JUCE_USE_FLAC
Enables the FLAC audio codec classes (available on all platforms).
If your app doesn't need to read FLAC files, you might want to disable this to
@@ -81,7 +81,7 @@
#define JUCE_USE_WINDOWS_MEDIA_FORMAT 0
#endif
//=============================================================================
//==============================================================================
namespace juce
{


+ 102
- 16
libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp View File

@@ -29,8 +29,8 @@
#include "../utility/juce_IncludeSystemHeaders.h"
#include "../utility/juce_IncludeModuleHeaders.h"
#include "../utility/juce_WindowsHooks.h"
#include "../utility/juce_PluginBusUtilities.h"
#undef Component
#ifdef __clang__
#pragma clang diagnostic push
@@ -40,7 +40,7 @@
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4127)
#pragma warning (disable : 4127 4512)
#endif
#include "AAX_Exports.cpp"
@@ -93,8 +93,6 @@
#undef check
using juce::Component;
const int32_t juceChunkType = 'juce';
//==============================================================================
@@ -115,6 +113,15 @@ struct AAXClasses
return AAX::IsParameterIDEqual (paramID, cDefaultMasterBypassID) != 0;
}
// maps a channel index of an AAX format to an index of a juce format
struct AAXChannelStreamOrder
{
AAX_EStemFormat aaxStemFormat;
AudioChannelSet::ChannelType speakerOrder[8];
};
static AAXChannelStreamOrder aaxChannelOrder[];
static AAX_EStemFormat getFormatForAudioChannelSet (const AudioChannelSet& set, bool ignoreLayout) noexcept
{
// if the plug-in ignores layout, it is ok to convert between formats only by their numchannnels
@@ -223,6 +230,24 @@ struct AAXClasses
return Colours::black;
}
static int juceChannelIndexToAax (int juceIndex, const AudioChannelSet& channelSet)
{
AAX_EStemFormat currentLayout = getFormatForAudioChannelSet (channelSet, false);
int layoutIndex;
for (layoutIndex = 0; aaxChannelOrder[layoutIndex].aaxStemFormat != currentLayout; ++layoutIndex)
if (aaxChannelOrder[layoutIndex].aaxStemFormat == 0) return juceIndex;
const AAXChannelStreamOrder& channelOrder = aaxChannelOrder[layoutIndex];
const AudioChannelSet::ChannelType channelType = channelSet.getTypeOfChannel (static_cast<int> (juceIndex));
for (int i = 0; i < 8 && channelOrder.speakerOrder[i] != 0; ++i)
if (channelOrder.speakerOrder[i] == channelType)
return i;
return juceIndex;
}
//==============================================================================
class JuceAAX_Processor;
@@ -381,7 +406,7 @@ struct AAXClasses
}
private:
struct ContentWrapperComponent : public juce::Component
struct ContentWrapperComponent : public Component
{
ContentWrapperComponent (JuceAAX_GUI& gui, AudioProcessor& plugin)
: owner (gui)
@@ -449,6 +474,10 @@ struct AAXClasses
ScopedPointer<AudioProcessorEditor> pluginEditor;
JuceAAX_GUI& owner;
#if JUCE_WINDOWS
WindowsHooks hooks;
#endif
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent)
};
@@ -839,7 +868,7 @@ struct AAXClasses
jassert (idx < (mainNumIns + 1));
if (idx < mainNumIns)
return inputs[idx];
return inputs[inputLayoutMap[idx]];
return (sidechain != -1 ? inputs[sidechain] : sideChainBuffer.getData());
}
@@ -860,26 +889,32 @@ struct AAXClasses
{
const int mainNumIns = numIns > 0 ? pluginInstance->busArrangement.inputBuses.getReference (0).channels.size() : 0;
const int sidechain = busUtils.getNumEnabledBuses (true) >= 2 ? sideChainBufferIdx : -1;
const int numChans = jmax (numIns, numOuts);
if (numChans == 0) return;
if (channelList.size() <= numChans)
channelList.insertMultiple (-1, nullptr, 1 + numChans - channelList.size());
float** channels = channelList.getRawDataPointer();
if (numOuts >= numIns)
{
for (int i = 0; i < numOuts; ++i)
channels[i] = outputs[outputLayoutMap[i]];
for (int i = 0; i < numIns; ++i)
memcpy (outputs[i], getAudioBufferForInput (inputs, sidechain, mainNumIns, i), (size_t) bufferSize * sizeof (float));
memcpy (channels[i], getAudioBufferForInput (inputs, sidechain, mainNumIns, i), (size_t) bufferSize * sizeof (float));
process (outputs, numOuts, bufferSize, bypass, midiNodeIn, midiNodesOut);
process (channels, numOuts, bufferSize, bypass, midiNodeIn, midiNodesOut);
}
else
{
if (channelList.size() <= numIns)
channelList.insertMultiple (-1, nullptr, 1 + numIns - channelList.size());
float** channels = channelList.getRawDataPointer();
for (int i = 0; i < numOuts; ++i)
channels[i] = outputs[outputLayoutMap[i]];
for (int i = 0; i < numOuts; ++i)
{
memcpy (outputs[i], getAudioBufferForInput (inputs, sidechain, mainNumIns, i), (size_t) bufferSize * sizeof (float));
channels[i] = outputs[i];
}
memcpy (channels[i], getAudioBufferForInput (inputs, sidechain, mainNumIns, i), (size_t) bufferSize * sizeof (float));
for (int i = numOuts; i < numIns; ++i)
channels[i] = const_cast<float*> (getAudioBufferForInput (inputs, sidechain, mainNumIns, i));
@@ -1060,6 +1095,9 @@ struct AAXClasses
|| (busUtils.getBusCount (false) > 0 && busUtils.getChannelSet (false, 0) != outputSet)
|| (hasSidechain && busUtils.getNumChannels(true, 1) != 1))
return AAX_ERROR_UNIMPLEMENTED;
rebuildChannelMapArrays (true);
rebuildChannelMapArrays (false);
#endif
audioProcessor.setRateAndBufferSizeDetails (sampleRate, maxBufferSize);
@@ -1071,6 +1109,30 @@ struct AAXClasses
return AAX_SUCCESS;
}
void rebuildChannelMapArrays (bool isInput)
{
Array<int>& layoutMap = isInput ? inputLayoutMap : outputLayoutMap;
layoutMap.clear();
const int n = isInput ? jmin (busUtils.getBusCount (true), 1) : busUtils.getBusCount (false);
int chOffset = 0;
for (int busIdx = 0; busIdx < n; ++busIdx)
{
const AudioChannelSet channelFormat = busUtils.getChannelSet (isInput, busIdx);
if (channelFormat != AudioChannelSet::disabled())
{
const int numChannels = channelFormat.size();
for (int ch = 0; ch < numChannels; ++ch)
layoutMap.add (juceChannelIndexToAax (ch, channelFormat) + chOffset);
chOffset += numChannels;
}
}
}
ScopedJuceInitialiser_GUI libraryInitialiser;
ScopedPointer<AudioProcessor> pluginInstance;
@@ -1082,6 +1144,7 @@ struct AAXClasses
int lastBufferSize, maxBufferSize;
bool hasSidechain;
HeapBlock<float> sideChainBuffer;
Array<int> inputLayoutMap, outputLayoutMap;
struct ChunkMemoryBlock : public ReferenceCountedObject
{
@@ -1308,6 +1371,10 @@ struct AAXClasses
properties->AddProperty (AAX_eProperty_Constraint_MultiMonoSupport, true);
#endif
#if JucePlugin_AAXDisableDynamicProcessing
properties->AddProperty (AAX_eProperty_Constraint_AlwaysProcess, true);
#endif
if (enableAuxBusesForCurrentFormat (busUtils, inputLayout, outputLayout))
{
check (desc.AddSideChainIn (JUCEAlgorithmIDs::sideChainBuffers));
@@ -1442,6 +1509,25 @@ struct AAXClasses
}
};
//==============================================================================
AAXClasses::AAXChannelStreamOrder AAXClasses::aaxChannelOrder[] =
{
{AAX_eStemFormat_Mono, {AudioChannelSet::centre, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_Stereo, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_LCR, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_LCRS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::surround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_Quad, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_5_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_5_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::subbass, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_6_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surround, AudioChannelSet::surroundRight, AudioChannelSet::unknown, AudioChannelSet::unknown}},
{AAX_eStemFormat_6_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surround, AudioChannelSet::surroundRight, AudioChannelSet::subbass, AudioChannelSet::unknown}},
{AAX_eStemFormat_7_0_SDDS, {AudioChannelSet::left, AudioChannelSet::centreLeft, AudioChannelSet::centre, AudioChannelSet::centreRight, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::unknown}},
{AAX_eStemFormat_7_0_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::sideLeft, AudioChannelSet::sideRight, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::unknown}},
{AAX_eStemFormat_7_1_SDDS, {AudioChannelSet::left, AudioChannelSet::centreLeft, AudioChannelSet::centre, AudioChannelSet::centreRight, AudioChannelSet::right, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::subbass}},
{AAX_eStemFormat_7_1_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::sideLeft, AudioChannelSet::sideRight, AudioChannelSet::surroundLeft, AudioChannelSet::surroundRight, AudioChannelSet::subbass}},
{AAX_eStemFormat_None, {AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}},
};
//==============================================================================
AAX_Result JUCE_CDECL GetEffectDescriptions (AAX_ICollection*);
AAX_Result JUCE_CDECL GetEffectDescriptions (AAX_ICollection* collection)


+ 200
- 65
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -48,22 +48,7 @@
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioUnitUtilities.h>
#include <CoreMIDI/MIDIServices.h>
#if JUCE_SUPPORT_CARBON
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#endif
/*
Got an include error here?
You probably need to install Apple's AU classes - see the
juce website for more info on how to get them:
http://www.juce.com/forum/topic/aus-xcode
*/
#include "CoreAudioUtilityClasses/MusicDeviceBase.h"
#undef Point
#undef Component
/** The BUILD_AU_CARBON_UI flag lets you specify whether old-school carbon hosts are supported as
well as ones that can open a cocoa view. If this is enabled, you'll need to also add the AUCarbonBase
@@ -78,10 +63,7 @@
#endif
#if BUILD_AU_CARBON_UI
#undef Button
#define Point CarbonDummyPointName
#include "CoreAudioUtilityClasses/AUCarbonViewBase.h"
#undef Point
#endif
#ifdef __clang__
@@ -89,12 +71,12 @@
#endif
#define JUCE_MAC_WINDOW_VISIBITY_BODGE 1
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
#include "../utility/juce_IncludeModuleHeaders.h"
#include "../utility/juce_FakeMouseMoveGenerator.h"
#include "../utility/juce_CarbonVisibility.h"
#include "../utility/juce_PluginBusUtilities.h"
#include "../../juce_core/native/juce_osx_ObjCHelpers.h"
//==============================================================================
static Array<void*> activePlugins, activeUIs;
@@ -976,7 +958,7 @@ public:
}
//==============================================================================
ComponentResult Render (AudioUnitRenderActionFlags &ioActionFlags,
ComponentResult Render (AudioUnitRenderActionFlags& ioActionFlags,
const AudioTimeStamp& inTimeStamp,
const UInt32 nFrames) override
{
@@ -988,7 +970,7 @@ public:
for (unsigned int i = 0; i < numInputBuses; ++i)
{
AudioUnitRenderActionFlags flags = ioActionFlags;
AUInputElement* input = GetInput (i);
AUInputElement* input = GetInput (i);
OSStatus result = input->PullInput (flags, inTimeStamp, i, nFrames);
@@ -1025,20 +1007,23 @@ public:
for (unsigned int chIdx = 0; chIdx < numOutChannels; ++chIdx)
{
int mappedInChIdx = numInChannels > 0 ? inputLayoutMap.getReference (static_cast<int> (busIdx))[static_cast<int> (chIdx)] : 0;
int mappedOutChIdx = outputLayoutMap.getReference (static_cast<int> (busIdx))[static_cast<int> (chIdx)];
const bool isOutputInterleaved = (numOutChannels > 1) && (outBuffer.mNumberBuffers == 1);
float* outData = isOutputInterleaved ? scratchBuffers[scratchIdx++] : static_cast<float*> (outBuffer.mBuffers[chIdx].mData);
float* outData = isOutputInterleaved ? scratchBuffers[scratchIdx++] : static_cast<float*> (outBuffer.mBuffers[mappedOutChIdx].mData);
if (chIdx < numInChannels)
{
const AudioBufferList& inBuffer = input->GetBufferList();
const bool isInputInterleaved = (numInChannels > 1) && (inBuffer.mNumberBuffers == 1);
const float* inData = static_cast<float*> (inBuffer.mBuffers[isInputInterleaved ? 0 : chIdx].mData);
const float* inData = static_cast<float*> (inBuffer.mBuffers[isInputInterleaved ? 0 : mappedInChIdx].mData);
if (isInputInterleaved)
{
for (unsigned int i = 0; i < nFrames; ++i)
{
outData [i] = inData[chIdx];
outData [i] = inData[mappedInChIdx];
inData += numInChannels;
}
}
@@ -1056,15 +1041,17 @@ public:
for (unsigned int chIdx = 0; chIdx < numInChannels; ++chIdx)
{
int mappedInChIdx = inputLayoutMap.getReference (static_cast<int> (busIdx))[static_cast<int> (chIdx)];
float* buffer = isInputInterleaved ? scratchBuffers[scratchIdx++]
: static_cast<float*> (inBuffer.mBuffers[chIdx].mData);
: static_cast<float*> (inBuffer.mBuffers[mappedInChIdx].mData);
if (isInputInterleaved)
{
const float* inData = static_cast<float*> (inBuffer.mBuffers[0].mData);
for (unsigned int i = 0; i < nFrames; ++i)
{
buffer [i] = inData [chIdx];
buffer [i] = inData [mappedInChIdx];
inData += numInChannels;
}
}
@@ -1114,32 +1101,45 @@ public:
const unsigned int numInChannels = (input != nullptr ? input ->GetStreamFormat().mChannelsPerFrame : 0);
const unsigned int numOutChannels = (output != nullptr ? output->GetStreamFormat().mChannelsPerFrame : 0);
if (numOutChannels > 0 && numInChannels >= numOutChannels)
if (numInChannels >= numOutChannels)
{
// the input buffers were used. We must copy the output
if (output->WillAllocateBuffer())
output->PrepareBuffer (nFrames);
const AudioBufferList& outBuffer = output->GetBufferList();
const bool isOutputInterleaved = (numOutChannels > 1) && (outBuffer.mNumberBuffers == 1);
for (unsigned int chIdx = 0; chIdx < numOutChannels; ++chIdx)
if (numOutChannels > 0)
{
float* outData = static_cast<float*> (outBuffer.mBuffers[isOutputInterleaved ? 0 : chIdx].mData);
const float* buffer = static_cast<float*> (channels [idx++]);
// the input buffers were used. We must copy the output
if (output->WillAllocateBuffer())
output->PrepareBuffer (nFrames);
if (isOutputInterleaved)
const AudioBufferList& outBuffer = output->GetBufferList();
const bool isOutputInterleaved = (numOutChannels > 1) && (outBuffer.mNumberBuffers == 1);
for (unsigned int chIdx = 0; chIdx < numOutChannels; ++chIdx)
{
for (unsigned int i = 0; i < nFrames; ++i)
int mappedOutChIdx = outputLayoutMap.getReference (static_cast<int> (busIdx))[static_cast<int> (chIdx)];
float* outData = static_cast<float*> (outBuffer.mBuffers[isOutputInterleaved ? 0 : mappedOutChIdx].mData);
float* buffer = static_cast<float*> (channels [idx]);
if (isOutputInterleaved)
{
outData [chIdx] = buffer[i];
outData += numOutChannels;
for (unsigned int i = 0; i < nFrames; ++i)
{
outData [mappedOutChIdx] = buffer[i];
outData += numOutChannels;
}
}
else
std::copy (buffer, buffer + nFrames, outData);
zeromem (buffer, sizeof(float) * nFrames);
idx++;
}
else
std::copy (buffer, buffer + nFrames, outData);
idx += numInChannels - numOutChannels;
}
else
{
for (unsigned int chIdx = 0; chIdx < numOutChannels; ++chIdx)
zeromem (channels [chIdx], sizeof(float) * nFrames);
}
idx += numInChannels - numOutChannels;
}
}
}
@@ -1187,12 +1187,6 @@ public:
midiEvents.clear();
}
#if ! JucePlugin_SilenceInProducesSilenceOut
ioActionFlags &= (AudioUnitRenderActionFlags) ~kAudioUnitRenderAction_OutputIsSilence;
#else
ignoreUnused (ioActionFlags);
#endif
return noErr;
}
@@ -1545,6 +1539,7 @@ private:
Array<AUChannelInfo> channelInfo;
Array<Array<AudioChannelLayoutTag> > supportedInputLayouts, supportedOutputLayouts;
Array<AudioChannelLayoutTag> currentInputLayout, currentOutputLayout;
Array<Array<int> > inputLayoutMap, outputLayoutMap;
//==============================================================================
static OSStatus scopeToDirection (AudioUnitScope scope, bool& isInput) noexcept
@@ -1601,13 +1596,22 @@ private:
OSStatus syncProcessorWithAudioUnit()
{
OSStatus err;
const int numInputBuses = busUtils.getBusCount (true);
const int numOutputBuses = busUtils.getBusCount (false);
const int numInputElements = static_cast<int> (GetScope(kAudioUnitScope_Input). GetNumberOfElements());
const int numOutputElements = static_cast<int> (GetScope(kAudioUnitScope_Output).GetNumberOfElements());
for (int i = 0; i < numInputElements; ++i)
inputLayoutMap. clear();
outputLayoutMap.clear();
inputLayoutMap. resize (numInputBuses);
outputLayoutMap.resize (numOutputBuses);
for (int i = 0; i < numInputBuses; ++i)
if ((err = syncProcessorWithAudioUnitForBus (true, i)) != noErr) return err;
for (int i = 0; i < numOutputElements; ++i)
for (int i = 0; i < numOutputBuses; ++i)
if ((err = syncProcessorWithAudioUnitForBus (false, i)) != noErr) return err;
if (numInputElements != busUtils.getNumEnabledBuses (true) || numOutputElements != busUtils.getNumEnabledBuses (false))
@@ -1626,23 +1630,29 @@ private:
//==============================================================================
OSStatus syncProcessorWithAudioUnitForBus (bool isInput, int busNr)
{
if (const AUIOElement* element = GetIOElement (isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output, (UInt32) busNr))
{
const int numChannels = static_cast<int> (element->GetStreamFormat().NumberChannels());
jassert (isPositiveAndBelow (busNr, busUtils.getBusCount (isInput)));
AudioChannelLayoutTag currentLayoutTag = isInput ? currentInputLayout[busNr] : currentOutputLayout[busNr];
const int tagNumChannels = currentLayoutTag & 0xffff;
const int numAUElements = static_cast<int> (GetScope(isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output).GetNumberOfElements());
const AUIOElement* element = (busNr < numAUElements ? GetIOElement (isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output, (UInt32) busNr) : nullptr);
const int numChannels = (element != nullptr ? static_cast<int> (element->GetStreamFormat().NumberChannels()) : 0);
if (numChannels != tagNumChannels)
return kAudioUnitErr_FormatNotSupported;
AudioChannelLayoutTag currentLayoutTag = isInput ? currentInputLayout[busNr] : currentOutputLayout[busNr];
const int tagNumChannels = currentLayoutTag & 0xffff;
if (juceFilter->setPreferredBusArrangement (isInput, busNr, CALayoutTagToChannelSet(currentLayoutTag)))
return noErr;
}
else
jassertfalse;
if (numChannels != tagNumChannels)
return kAudioUnitErr_FormatNotSupported;
const AudioChannelSet channelFormat = CALayoutTagToChannelSet(currentLayoutTag);
if (! juceFilter->setPreferredBusArrangement (isInput, busNr, channelFormat))
return kAudioUnitErr_FormatNotSupported;
return kAudioUnitErr_FormatNotSupported;
Array<int>& layoutMap = (isInput ? inputLayoutMap : outputLayoutMap).getReference (busNr);
for (int i = 0; i < numChannels; ++i)
layoutMap.add (auChannelIndexToJuce (i, channelFormat));
return noErr;
}
OSStatus syncAudioUnitWithChannelSet (bool isInput, int busNr, const AudioChannelSet& channelSet)
@@ -1877,6 +1887,50 @@ private:
}
//==============================================================================
// maps a channel index into an AU format to an index of a juce format
struct AUChannelStreamOrder
{
AudioChannelLayoutTag auLayoutTag;
AudioChannelLabel speakerOrder[8];
};
static AUChannelStreamOrder auChannelStreamOrder[];
static int auChannelIndexToJuce (int auIndex, const AudioChannelSet& channelSet)
{
if (auIndex >= 8) return auIndex;
AudioChannelLayoutTag currentLayout = ChannelSetToCALayoutTag (channelSet);
int layoutIndex;
for (layoutIndex = 0; auChannelStreamOrder[layoutIndex].auLayoutTag != currentLayout; ++layoutIndex)
if (auChannelStreamOrder[layoutIndex].auLayoutTag == 0) return auIndex;
const AudioChannelSet::ChannelType channelType
= CoreAudioChannelLabelToJuceType (auChannelStreamOrder[layoutIndex].speakerOrder[auIndex]);
const int juceIndex = channelSet.getChannelTypes().indexOf (channelType);
return juceIndex >= 0 ? juceIndex : auIndex;
}
static int juceChannelIndexToAu (int juceIndex, const AudioChannelSet& channelSet)
{
AudioChannelLayoutTag currentLayout = ChannelSetToCALayoutTag (channelSet);
int layoutIndex;
for (layoutIndex = 0; auChannelStreamOrder[layoutIndex].auLayoutTag != currentLayout; ++layoutIndex)
if (auChannelStreamOrder[layoutIndex].auLayoutTag == 0) return juceIndex;
const AUChannelStreamOrder& channelOrder = auChannelStreamOrder[layoutIndex];
const AudioChannelSet::ChannelType channelType = channelSet.getTypeOfChannel (juceIndex);
for (int i = 0; i < 8 && channelOrder.speakerOrder[i] != 0; ++i)
if (CoreAudioChannelLabelToJuceType (channelOrder.speakerOrder[i]) == channelType)
return i;
return juceIndex;
}
static AudioChannelSet::ChannelType CoreAudioChannelLabelToJuceType (AudioChannelLabel label) noexcept
{
if (label >= kAudioChannelLabel_Discrete_0 && label <= kAudioChannelLabel_Discrete_65535)
@@ -1911,10 +1965,58 @@ private:
case kAudioChannelLabel_RearSurroundRight: return AudioChannelSet::topRearRight;
case kAudioChannelLabel_TopBackCenter: return AudioChannelSet::topRearCentre;
case kAudioChannelLabel_LFE2: return AudioChannelSet::subbass2;
case kAudioChannelLabel_LeftWide: return AudioChannelSet::wideLeft;
case kAudioChannelLabel_RightWide: return AudioChannelSet::wideRight;
case kAudioChannelLabel_Ambisonic_W: return AudioChannelSet::ambisonicW;
case kAudioChannelLabel_Ambisonic_X: return AudioChannelSet::ambisonicX;
case kAudioChannelLabel_Ambisonic_Y: return AudioChannelSet::ambisonicY;
case kAudioChannelLabel_Ambisonic_Z: return AudioChannelSet::ambisonicZ;
default: return AudioChannelSet::unknown;
}
}
static AudioChannelLabel JuceChannelTypeToCoreAudioLabel (const AudioChannelSet::ChannelType& label) noexcept
{
if (label >= AudioChannelSet::discreteChannel0)
{
const unsigned int discreteChannelNum = label - AudioChannelSet::discreteChannel0;;
return static_cast<AudioChannelLabel> (kAudioChannelLabel_Discrete_0 + discreteChannelNum);
}
switch (label)
{
case AudioChannelSet::centre: return kAudioChannelLabel_Center;
case AudioChannelSet::left: return kAudioChannelLabel_Left;
case AudioChannelSet::right: return kAudioChannelLabel_Right;
case AudioChannelSet::subbass: return kAudioChannelLabel_LFEScreen;
case AudioChannelSet::surroundLeft: return kAudioChannelLabel_LeftSurround;
case AudioChannelSet::surroundRight: return kAudioChannelLabel_RightSurround;
case AudioChannelSet::centreLeft: return kAudioChannelLabel_LeftCenter;
case AudioChannelSet::centreRight: return kAudioChannelLabel_RightCenter;
case AudioChannelSet::surround: return kAudioChannelLabel_CenterSurround;
case AudioChannelSet::sideLeft: return kAudioChannelLabel_LeftSurroundDirect;
case AudioChannelSet::sideRight: return kAudioChannelLabel_RightSurroundDirect;
case AudioChannelSet::topMiddle: return kAudioChannelLabel_TopCenterSurround;
case AudioChannelSet::topFrontLeft: return kAudioChannelLabel_VerticalHeightLeft;
case AudioChannelSet::topFrontRight: return kAudioChannelLabel_VerticalHeightRight;
case AudioChannelSet::topFrontCentre: return kAudioChannelLabel_VerticalHeightCenter;
case AudioChannelSet::topRearLeft: return kAudioChannelLabel_RearSurroundLeft;
case AudioChannelSet::topRearRight: return kAudioChannelLabel_RearSurroundRight;
case AudioChannelSet::topRearCentre: return kAudioChannelLabel_TopBackCenter;
case AudioChannelSet::subbass2: return kAudioChannelLabel_LFE2;
case AudioChannelSet::wideLeft: return kAudioChannelLabel_LeftWide;
case AudioChannelSet::wideRight: return kAudioChannelLabel_RightWide;
case AudioChannelSet::ambisonicW: return kAudioChannelLabel_Ambisonic_W;
case AudioChannelSet::ambisonicX: return kAudioChannelLabel_Ambisonic_X;
case AudioChannelSet::ambisonicY: return kAudioChannelLabel_Ambisonic_Y;
case AudioChannelSet::ambisonicZ: return kAudioChannelLabel_Ambisonic_Z;
case AudioChannelSet::unknown: return kAudioChannelLabel_Unknown;
case AudioChannelSet::discreteChannel0: return kAudioChannelLabel_Discrete_0;
}
return kAudioChannelLabel_Unknown;
}
static AudioChannelSet CoreAudioChannelBitmapToJuceType (UInt32 bitmap) noexcept
{
AudioChannelSet set;
@@ -1962,6 +2064,7 @@ private:
{
switch (tag)
{
case kAudioChannelLayoutTag_Unknown: return AudioChannelSet::disabled();
case kAudioChannelLayoutTag_Mono: return AudioChannelSet::mono();
case kAudioChannelLayoutTag_Stereo:
case kAudioChannelLayoutTag_StereoHeadphones:
@@ -1979,6 +2082,10 @@ private:
case kAudioChannelLayoutTag_MPEG_7_1_C: return AudioChannelSet::create7point1();
case kAudioChannelLayoutTag_AudioUnit_7_0_Front: return AudioChannelSet::createFront7point0();
case kAudioChannelLayoutTag_AudioUnit_7_1_Front: return AudioChannelSet::createFront7point1();
case kAudioChannelLayoutTag_MPEG_3_0_A:
case kAudioChannelLayoutTag_MPEG_3_0_B: return AudioChannelSet::createLCR();
case kAudioChannelLayoutTag_MPEG_4_0_A:
case kAudioChannelLayoutTag_MPEG_4_0_B: return AudioChannelSet::createLCRS();
}
if (int numChannels = static_cast<int> (tag) & 0xffff)
@@ -1993,6 +2100,8 @@ private:
{
if (set == AudioChannelSet::mono()) return kAudioChannelLayoutTag_Mono;
if (set == AudioChannelSet::stereo()) return kAudioChannelLayoutTag_Stereo;
if (set == AudioChannelSet::createLCR()) return kAudioChannelLayoutTag_MPEG_3_0_A;
if (set == AudioChannelSet::createLCRS()) return kAudioChannelLayoutTag_MPEG_4_0_A;
if (set == AudioChannelSet::quadraphonic()) return kAudioChannelLayoutTag_Quadraphonic;
if (set == AudioChannelSet::pentagonal()) return kAudioChannelLayoutTag_Pentagonal;
if (set == AudioChannelSet::hexagonal()) return kAudioChannelLayoutTag_Hexagonal;
@@ -2006,6 +2115,7 @@ private:
if (set == AudioChannelSet::create7point1()) return kAudioChannelLayoutTag_MPEG_7_1_C;
if (set == AudioChannelSet::createFront7point0()) return kAudioChannelLayoutTag_AudioUnit_7_0_Front;
if (set == AudioChannelSet::createFront7point1()) return kAudioChannelLayoutTag_AudioUnit_7_1_Front;
if (set == AudioChannelSet::disabled()) return kAudioChannelLayoutTag_Unknown;
return static_cast<AudioChannelLayoutTag> ((int) kAudioChannelLayoutTag_DiscreteInOrder | set.size());
}
@@ -2048,6 +2158,31 @@ private:
JUCE_DECLARE_NON_COPYABLE (JuceAU)
};
JuceAU::AUChannelStreamOrder JuceAU::auChannelStreamOrder[] =
{
{kAudioChannelLayoutTag_Mono, {kAudioChannelLabel_Center, 0, 0, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_Stereo, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, 0, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_StereoHeadphones, {kAudioChannelLabel_HeadphonesLeft, kAudioChannelLabel_HeadphonesRight, 0, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_Binaural, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, 0, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_Quadraphonic, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_Pentagonal, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, 0, 0, 0}},
{kAudioChannelLayoutTag_Hexagonal, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, kAudioChannelLabel_CenterSurround, 0, 0}},
{kAudioChannelLayoutTag_Octagonal, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, kAudioChannelLabel_CenterSurround, kAudioChannelLabel_LeftWide, kAudioChannelLabel_RightWide}},
{kAudioChannelLayoutTag_Ambisonic_B_Format, {kAudioChannelLabel_Ambisonic_W, kAudioChannelLabel_Ambisonic_X, kAudioChannelLabel_Ambisonic_Y, kAudioChannelLabel_Ambisonic_Z, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_MPEG_5_0_B, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, 0, 0, 0}},
{kAudioChannelLayoutTag_MPEG_5_1_A, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, kAudioChannelLabel_LFEScreen, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, 0, 0}},
{kAudioChannelLayoutTag_AudioUnit_6_0, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, kAudioChannelLabel_CenterSurround, 0, 0}},
{kAudioChannelLayoutTag_MPEG_6_1_A, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, kAudioChannelLabel_LFEScreen, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_CenterSurround, 0}},
{kAudioChannelLayoutTag_AudioUnit_7_0, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, kAudioChannelLabel_RearSurroundLeft, kAudioChannelLabel_RearSurroundRight, 0}},
{kAudioChannelLayoutTag_MPEG_7_1_C, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, kAudioChannelLabel_LFEScreen, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_RearSurroundLeft, kAudioChannelLabel_RearSurroundRight}},
{kAudioChannelLayoutTag_AudioUnit_7_0_Front,{kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_Center, kAudioChannelLabel_LeftCenter, kAudioChannelLabel_RightCenter, 0}},
{kAudioChannelLayoutTag_AudioUnit_7_1_Front,{kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, kAudioChannelLabel_LFEScreen, kAudioChannelLabel_LeftSurround, kAudioChannelLabel_RightSurround, kAudioChannelLabel_LeftCenter, kAudioChannelLabel_RightCenter}},
{kAudioChannelLayoutTag_MPEG_3_0_A, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_MPEG_3_0_B, {kAudioChannelLabel_Center, kAudioChannelLabel_Left, kAudioChannelLabel_Right, 0, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_MPEG_4_0_A, {kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_Center, kAudioChannelLabel_CenterSurround, 0, 0, 0, 0}},
{kAudioChannelLayoutTag_MPEG_4_0_B, {kAudioChannelLabel_Center, kAudioChannelLabel_Left, kAudioChannelLabel_Right, kAudioChannelLabel_CenterSurround, 0, 0, 0, 0}},
{0, {0,0,0,0,0,0,0,0}}
};
//==============================================================================
#if BUILD_AU_CARBON_UI


+ 0
- 2
libs/juce/source/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h View File

@@ -64,8 +64,6 @@
#define PLUGIN_SDK_DIRECTMIDI 1
#define DIGI_PASCAL
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#include <MacAlwaysInclude.h>
#endif


+ 14
- 18
libs/juce/source/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp View File

@@ -86,9 +86,6 @@
#include <FicProcessTokens.h>
#include <ExternalVersionDefines.h>
#undef Point
#undef Component
//==============================================================================
#ifdef _MSC_VER
#pragma pack (push, 8)
@@ -122,19 +119,18 @@
#pragma comment(lib, PT_LIB_PATH "RTASClientLib.lib")
#endif
#undef Component
#undef MemoryBlock
//==============================================================================
#if JUCE_WINDOWS
extern void JUCE_CALLTYPE attachSubWindow (void* hostWindow, int& titleW, int& titleH, juce::Component* comp);
extern void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, int& titleW, int& titleH, juce::Component* comp);
extern void JUCE_CALLTYPE attachSubWindow (void* hostWindow, int& titleW, int& titleH, Component* comp);
extern void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, int& titleW, int& titleH, Component* comp);
#if ! JucePlugin_EditorRequiresKeyboardFocus
extern void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow);
#endif
#else
extern void* attachSubWindow (void* hostWindowRef, juce::Component* comp);
extern void removeSubWindow (void* nsWindow, juce::Component* comp);
extern void* attachSubWindow (void* hostWindowRef, Component* comp);
extern void removeSubWindow (void* nsWindow, Component* comp);
extern void forwardCurrentKeyEventToHostWindow();
#endif
@@ -240,7 +236,7 @@ public:
void timerCallback() override
{
if (! juce::Component::isMouseButtonDownAnywhere())
if (! Component::isMouseButtonDownAnywhere())
{
stopTimer();
@@ -290,7 +286,7 @@ public:
private:
AudioProcessor* const filter;
JucePlugInProcess* const process;
ScopedPointer<juce::Component> wrapper;
ScopedPointer<Component> wrapper;
ScopedPointer<AudioProcessorEditor> editorComp;
void deleteEditorComp()
@@ -301,7 +297,7 @@ public:
{
PopupMenu::dismissAllActiveMenus();
if (juce::Component* const modalComponent = juce::Component::getCurrentlyModalComponent())
if (Component* const modalComponent = Component::getCurrentlyModalComponent())
modalComponent->exitModalState (0);
filter->editorBeingDeleted (editorComp);
@@ -315,7 +311,7 @@ public:
//==============================================================================
// A component to hold the AudioProcessorEditor, and cope with some housekeeping
// chores when it changes or repaints.
class EditorCompWrapper : public juce::Component
class EditorCompWrapper : public Component
#if ! JUCE_MAC
, public FocusChangeListener
#endif
@@ -368,14 +364,14 @@ public:
void resized() override
{
if (juce::Component* const ed = getEditor())
if (Component* const ed = getEditor())
ed->setBounds (getLocalBounds());
repaint();
}
#if JUCE_WINDOWS
void globalFocusChanged (juce::Component*) override
void globalFocusChanged (Component*) override
{
#if ! JucePlugin_EditorRequiresKeyboardFocus
if (hasKeyboardFocus (true))
@@ -384,7 +380,7 @@ public:
}
#endif
void childBoundsChanged (juce::Component* child) override
void childBoundsChanged (Component* child) override
{
setSize (child->getWidth(), child->getHeight());
child->setTopLeftPosition (0, 0);
@@ -413,7 +409,7 @@ public:
JuceCustomUIView* const owner;
int titleW, titleH;
juce::Component* getEditor() const { return getChildComponent (0); }
Component* getEditor() const { return getChildComponent (0); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper)
};
@@ -666,9 +662,9 @@ public:
#if JUCE_WINDOWS
Boolean HandleKeystroke (EventRecord* e) override
{
if (juce::Component* modalComp = juce::Component::getCurrentlyModalComponent())
if (Component* modalComp = Component::getCurrentlyModalComponent())
{
if (juce::Component* focused = modalComp->getCurrentlyFocusedComponent())
if (Component* focused = modalComp->getCurrentlyFocusedComponent())
{
switch (e->message & charCodeMask)
{


+ 32
- 13
libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -40,15 +40,27 @@ class StandalonePluginHolder
public:
/** Creates an instance of the default plugin.
The settings object can be a PropertySet that the class should use to
store its settings - the object that is passed-in will be owned by this
class and deleted automatically when no longer needed. (It can also be null)
The settings object can be a PropertySet that the class should use to store its
settings - the takeOwnershipOfSettings indicates whether this object will delete
the settings automatically when no longer needed. The settings can also be nullptr.
A default device name can be passed in.
Preferably a complete setup options object can be used, which takes precedence over
the preferredDefaultDeviceName and allows you to select the input & output device names,
sample rate, buffer size etc.
In all instances, the settingsToUse will take precedence over the "preferred" options if not null.
*/
StandalonePluginHolder (PropertySet* settingsToUse, bool takeOwnershipOfSettings)
StandalonePluginHolder (PropertySet* settingsToUse,
bool takeOwnershipOfSettings = true,
const String& preferredDefaultDeviceName = String(),
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr)
: settings (settingsToUse, takeOwnershipOfSettings)
{
createPlugin();
setupAudioDevices();
setupAudioDevices (preferredDefaultDeviceName, preferredSetupOptions);
reloadPluginState();
startPlaying();
}
@@ -189,7 +201,8 @@ public:
}
}
void reloadAudioDeviceState()
void reloadAudioDeviceState (const String& preferredDefaultDeviceName,
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions)
{
ScopedPointer<XmlElement> savedState;
@@ -199,7 +212,9 @@ public:
deviceManager.initialise (processor->getTotalNumInputChannels(),
processor->getTotalNumOutputChannels(),
savedState,
true);
true,
preferredDefaultDeviceName,
preferredSetupOptions);
}
//==============================================================================
@@ -232,19 +247,20 @@ public:
AudioProcessorPlayer player;
private:
void setupAudioDevices()
void setupAudioDevices (const String& preferredDefaultDeviceName,
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions)
{
deviceManager.addAudioCallback (&player);
deviceManager.addMidiInputCallback (String::empty, &player);
deviceManager.addMidiInputCallback (String(), &player);
reloadAudioDeviceState();
reloadAudioDeviceState (preferredDefaultDeviceName, preferredSetupOptions);
}
void shutDownAudioDevices()
{
saveAudioDeviceState();
deviceManager.removeMidiInputCallback (String::empty, &player);
deviceManager.removeMidiInputCallback (String(), &player);
deviceManager.removeAudioCallback (&player);
}
@@ -273,7 +289,9 @@ public:
StandaloneFilterWindow (const String& title,
Colour backgroundColour,
PropertySet* settingsToUse,
bool takeOwnershipOfSettings)
bool takeOwnershipOfSettings,
const String& preferredDefaultDeviceName = String(),
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr)
: DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton),
optionsButton ("options")
{
@@ -283,7 +301,8 @@ public:
optionsButton.addListener (this);
optionsButton.setTriggeredOnMouseDown (true);
pluginHolder = new StandalonePluginHolder (settingsToUse, takeOwnershipOfSettings);
pluginHolder = new StandalonePluginHolder (settingsToUse, takeOwnershipOfSettings,
preferredDefaultDeviceName, preferredSetupOptions);
createEditorComp();


+ 199
- 145
libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp View File

@@ -110,7 +110,6 @@
class JuceVSTWrapper;
static bool recursionCheck = false;
static juce::uint32 lastMasterIdleCall = 0;
namespace juce
{
@@ -277,14 +276,43 @@ public:
#endif
hostWindow (0)
{
int maxNumInChannels, maxNumOutChannels;
busUtils.findAllCompatibleLayouts();
// VST-2 does not support disabling buses: so always enable all of them
if (busUtils.hasDynamicInBuses() || busUtils.hasDynamicOutBuses())
busUtils.enableAllBuses();
const int totalNumInChannels = busUtils.findTotalNumChannels(true);
const int totalNumOutChannels = busUtils.findTotalNumChannels(false);
{
PluginBusUtilities::ScopedBusRestorer busRestorer (busUtils);
maxNumInChannels = busUtils.getBusCount (true) > 0 ? busUtils.getSupportedBusLayouts (true, 0).maxNumberOfChannels() : 0;
maxNumOutChannels = busUtils.getBusCount (false) > 0 ? busUtils.getSupportedBusLayouts (false, 0).maxNumberOfChannels() : 0;
if (hostOnlySupportsStereo())
{
maxNumInChannels = jmin (maxNumInChannels, 2);
maxNumOutChannels = jmin (maxNumOutChannels, 2);
}
// try setting the number of channels
if (maxNumInChannels > 0)
filter->setPreferredBusArrangement (true, 0, busUtils.getDefaultLayoutForChannelNumAndBus (true, 0, maxNumInChannels));
if (maxNumOutChannels > 0)
filter->setPreferredBusArrangement (false, 0, busUtils.getDefaultLayoutForChannelNumAndBus (false, 0, maxNumOutChannels));
resetAuxChannelsToDefaultLayout (true);
resetAuxChannelsToDefaultLayout (false);
maxNumInChannels = busUtils.findTotalNumChannels (true);
maxNumOutChannels = busUtils.findTotalNumChannels (false);
if ((busUtils.getBusCount (true) > 0 && busUtils.getDefaultLayoutForBus (true, 0) .size() > maxNumInChannels)
|| (busUtils.getBusCount (false) > 0 && busUtils.getDefaultLayoutForBus (false, 0).size() > maxNumOutChannels))
busRestorer.release();
}
filter->setRateAndBufferSizeDetails (0, 0);
filter->setPlayHead (this);
@@ -295,8 +323,8 @@ public:
setUniqueID ((int) (JucePlugin_VSTUniqueID));
setNumInputs (totalNumInChannels);
setNumOutputs (totalNumOutChannels);
setNumInputs (maxNumInChannels);
setNumOutputs (maxNumOutChannels);
canProcessReplacing (true);
canDoubleReplacing (filter->supportsDoublePrecisionProcessing());
@@ -544,7 +572,8 @@ public:
tmpBuffers.channels[i] = inputs[i];
{
AudioBuffer<FloatType> chans (tmpBuffers.channels, jmax (numIn, numOut), numSamples);
const int numChannels = jmax (numIn, numOut);
AudioBuffer<FloatType> chans (tmpBuffers.channels, numChannels, numSamples);
if (isBypassed)
filter->processBlockBypassed (chans, midiEvents);
@@ -641,31 +670,20 @@ public:
{
isProcessing = true;
const int numInChans = filter->busArrangement.getTotalNumInputChannels();
const int numOutChans = filter->busArrangement.getTotalNumOutputChannels();
setNumInputs (numInChans);
setNumOutputs (numOutChans);
floatTempBuffers.channels.calloc ((size_t) (numInChans + numOutChans));
doubleTempBuffers.channels.calloc ((size_t) (numInChans + numOutChans));
double rate = getSampleRate();
jassert (rate > 0);
if (rate <= 0.0)
rate = 44100.0;
floatTempBuffers .channels.calloc ((size_t) (cEffect.numInputs + cEffect.numOutputs));
doubleTempBuffers.channels.calloc ((size_t) (cEffect.numInputs + cEffect.numOutputs));
const double currentRate = getSampleRate();
const int currentBlockSize = getBlockSize();
jassert (currentBlockSize > 0);
firstProcessCallback = true;
filter->setNonRealtime (getCurrentProcessLevel() == 4 /* kVstProcessLevelOffline */);
filter->setRateAndBufferSizeDetails (rate, currentBlockSize);
filter->setRateAndBufferSizeDetails (currentRate, currentBlockSize);
deleteTempChannels();
filter->prepareToPlay (rate, currentBlockSize);
filter->prepareToPlay (currentRate, currentBlockSize);
midiEvents.ensureSize (2048);
midiEvents.clear();
@@ -901,10 +919,6 @@ public:
bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
VstSpeakerArrangement* pluginOutput) override
{
if ((busUtils.getBusCount (true) == 0 || busUtils.busIgnoresLayout(true, 0))
&& (busUtils.getBusCount (false) == 0 || busUtils.busIgnoresLayout(false, 0)))
return false;
if (pluginInput != nullptr && filter->busArrangement.inputBuses.size() == 0)
return false;
@@ -913,34 +927,64 @@ public:
PluginBusUtilities::ScopedBusRestorer busRestorer (busUtils);
if (pluginInput != nullptr)
resetAuxChannelsToDefaultLayout (true);
resetAuxChannelsToDefaultLayout (false);
if (pluginInput != nullptr && pluginInput->numChannels >= 0)
{
AudioChannelSet newType = SpeakerMappings::vstArrangementTypeToChannelSet (*pluginInput);
AudioChannelSet newType;
// subtract the number of channels which are used by the aux channels
int mainNumChannels = pluginInput->numChannels - busUtils.findTotalNumChannels (true, 1);
if (mainNumChannels <= 0)
return false;
if (mainNumChannels > busUtils.getSupportedBusLayouts (true, 0).maxNumberOfChannels())
return false;
newType = SpeakerMappings::vstArrangementTypeToChannelSet (*pluginInput);
if (mainNumChannels != newType.size())
newType = AudioChannelSet::canonicalChannelSet(mainNumChannels);
if (busUtils.getChannelSet (true, 0) != newType)
if (! filter->setPreferredBusArrangement (true, 0, newType))
return false;
}
if (pluginOutput != nullptr)
if (pluginOutput != nullptr && pluginOutput->numChannels >= 0)
{
AudioChannelSet newType = SpeakerMappings::vstArrangementTypeToChannelSet (*pluginOutput);
AudioChannelSet newType;
// subtract the number of channels which are used by the aux channels
int mainNumChannels = pluginOutput->numChannels - busUtils.findTotalNumChannels (false, 1);
if (mainNumChannels <= 0)
return false;
if (mainNumChannels > busUtils.getSupportedBusLayouts (false, 0).maxNumberOfChannels())
return false;
newType = SpeakerMappings::vstArrangementTypeToChannelSet (*pluginOutput);
if (mainNumChannels != newType.size())
newType = AudioChannelSet::canonicalChannelSet(mainNumChannels);
AudioChannelSet oldOutputLayout = busUtils.getChannelSet (false, 0);
AudioChannelSet oldInputLayout = busUtils.getChannelSet (true, 0);
if (busUtils.getChannelSet (false, 0) != newType)
if (! filter->setPreferredBusArrangement (false, 0, newType))
return false;
// did this change the input layout?
if (oldInputLayout != busUtils.getChannelSet (true, 0) && pluginInput != nullptr)
return false;
}
busRestorer.release();
const int totalNumInChannels = busUtils.findTotalNumChannels(true);
const int totalNumOutChannels = busUtils.findTotalNumChannels(false);
filter->setRateAndBufferSizeDetails(0, 0);
setNumInputs (totalNumInChannels);
setNumOutputs(totalNumOutChannels);
ioChanged();
return true;
}
@@ -950,22 +994,35 @@ public:
*pluginInput = 0;
*pluginOutput = 0;
if ((busUtils.getBusCount (true) == 0 || busUtils.busIgnoresLayout(true, 0))
&& (busUtils.getBusCount (false) == 0 || busUtils.busIgnoresLayout(false, 0)))
if (! AudioEffectX::allocateArrangement (pluginInput, busUtils.findTotalNumChannels (true)))
return false;
if (! AudioEffectX::allocateArrangement (pluginInput, busUtils.getNumChannels (true, 0)))
return false;
if (! AudioEffectX::allocateArrangement (pluginOutput, busUtils.getNumChannels (false, 0)))
if (! AudioEffectX::allocateArrangement (pluginOutput, busUtils.findTotalNumChannels (false)))
{
AudioEffectX::deallocateArrangement (pluginInput);
*pluginInput = 0;
return false;
}
SpeakerMappings::channelSetToVstArrangement (busUtils.getChannelSet (true, 0), **pluginInput);
SpeakerMappings::channelSetToVstArrangement (busUtils.getChannelSet (false, 0), **pluginOutput);
if (busUtils.getBusCount (true) > 1)
{
AudioChannelSet layout = AudioChannelSet::canonicalChannelSet (busUtils.findTotalNumChannels(true));
SpeakerMappings::channelSetToVstArrangement (layout, **pluginInput);
}
else
{
SpeakerMappings::channelSetToVstArrangement (busUtils.getChannelSet (true, 0), **pluginInput);
}
if (busUtils.getBusCount (false) > 1)
{
AudioChannelSet layout = AudioChannelSet::canonicalChannelSet (busUtils.findTotalNumChannels(false));
SpeakerMappings::channelSetToVstArrangement (layout, **pluginOutput);
}
else
{
SpeakerMappings::channelSetToVstArrangement (busUtils.getChannelSet (false, 0), **pluginOutput);
}
return true;
}
@@ -985,11 +1042,14 @@ public:
bool getPinProperties (VstPinProperties& properties, bool direction, int index) const
{
// index refers to the absolute index when combining all channels of every bus
if (index >= (direction ? cEffect.numInputs : cEffect.numOutputs))
return false;
const int n = busUtils.getBusCount(direction);
int busIdx;
for (busIdx = 0; busIdx < n; ++busIdx)
{
const int numChans = busUtils.getNumChannels(direction, busIdx);
const int numChans = busUtils.getNumChannels (direction, busIdx);
if (index < numChans)
break;
@@ -997,25 +1057,30 @@ public:
}
if (busIdx >= n)
return false;
{
properties.flags = kVstPinUseSpeaker;
properties.label[0] = 0;
properties.shortLabel[0] = 0;
properties.arrangementType = kSpeakerArrEmpty;
return true;
}
const AudioProcessor::AudioProcessorBus& busInfo = busUtils.getFilterBus (direction).getReference (busIdx);
busInfo.name.copyToUTF8 (properties.label, (size_t) (kVstMaxLabelLen - 1));
busInfo.name.copyToUTF8 (properties.shortLabel, (size_t) (kVstMaxShortLabelLen - 1));
String channelName = busInfo.name;
VstInt32 type = SpeakerMappings::channelSetToVstArrangementType (busInfo.channels);
channelName +=
String (" ") + AudioChannelSet::getAbbreviatedChannelTypeName (busInfo.channels.getTypeOfChannel(index));
if (type != kSpeakerArrEmpty)
{
properties.flags = kVstPinUseSpeaker | kVstPinIsActive;
properties.arrangementType = type;
}
else
{
properties.flags = 0;
properties.arrangementType = 0;
}
channelName.copyToUTF8 (properties.label, (size_t) (kVstMaxLabelLen - 1));
channelName.copyToUTF8 (properties.shortLabel, (size_t) (kVstMaxShortLabelLen - 1));
properties.flags = kVstPinUseSpeaker | kVstPinIsActive;
properties.arrangementType = SpeakerMappings::channelSetToVstArrangementType (busInfo.channels);
if (properties.arrangementType == kSpeakerArrEmpty)
properties.flags &= ~kVstPinIsActive;
if (busInfo.channels.size() == 2)
properties.flags |= kVstPinIsStereo;
@@ -1070,11 +1135,14 @@ public:
{
Array<AudioChannelSet::ChannelType> chans (channels.getChannelTypes());
if (channels == AudioChannelSet::disabled())
return kSpeakerArrEmpty;
for (const Mapping* m = getMappings(); m->vst2 != kSpeakerArrEmpty; ++m)
if (m->matches (chans))
return m->vst2;
return kSpeakerArrEmpty;
return kSpeakerArrUserDefined;
}
static void channelSetToVstArrangement (const AudioChannelSet& channels, VstSpeakerArrangement& result)
@@ -1134,25 +1202,25 @@ public:
{
switch (type)
{
case AudioChannelSet::ChannelType::left: return kSpeakerL;
case AudioChannelSet::ChannelType::right: return kSpeakerR;
case AudioChannelSet::ChannelType::centre: return kSpeakerC;
case AudioChannelSet::ChannelType::subbass: return kSpeakerLfe;
case AudioChannelSet::ChannelType::surroundLeft: return kSpeakerLs;
case AudioChannelSet::ChannelType::surroundRight: return kSpeakerRs;
case AudioChannelSet::ChannelType::centreLeft: return kSpeakerLc;
case AudioChannelSet::ChannelType::centreRight: return kSpeakerRc;
case AudioChannelSet::ChannelType::surround: return kSpeakerS;
case AudioChannelSet::ChannelType::sideLeft: return kSpeakerSl;
case AudioChannelSet::ChannelType::sideRight: return kSpeakerSr;
case AudioChannelSet::ChannelType::topMiddle: return kSpeakerTm;
case AudioChannelSet::ChannelType::topFrontLeft: return kSpeakerTfl;
case AudioChannelSet::ChannelType::topFrontCentre: return kSpeakerTfc;
case AudioChannelSet::ChannelType::topFrontRight: return kSpeakerTfr;
case AudioChannelSet::ChannelType::topRearLeft: return kSpeakerTrl;
case AudioChannelSet::ChannelType::topRearCentre: return kSpeakerTrc;
case AudioChannelSet::ChannelType::topRearRight: return kSpeakerTrr;
case AudioChannelSet::ChannelType::subbass2: return kSpeakerLfe2;
case AudioChannelSet::left: return kSpeakerL;
case AudioChannelSet::right: return kSpeakerR;
case AudioChannelSet::centre: return kSpeakerC;
case AudioChannelSet::subbass: return kSpeakerLfe;
case AudioChannelSet::surroundLeft: return kSpeakerLs;
case AudioChannelSet::surroundRight: return kSpeakerRs;
case AudioChannelSet::centreLeft: return kSpeakerLc;
case AudioChannelSet::centreRight: return kSpeakerRc;
case AudioChannelSet::surround: return kSpeakerS;
case AudioChannelSet::sideLeft: return kSpeakerSl;
case AudioChannelSet::sideRight: return kSpeakerSr;
case AudioChannelSet::topMiddle: return kSpeakerTm;
case AudioChannelSet::topFrontLeft: return kSpeakerTfl;
case AudioChannelSet::topFrontCentre: return kSpeakerTfc;
case AudioChannelSet::topFrontRight: return kSpeakerTfr;
case AudioChannelSet::topRearLeft: return kSpeakerTrl;
case AudioChannelSet::topRearCentre: return kSpeakerTrc;
case AudioChannelSet::topRearRight: return kSpeakerTrr;
case AudioChannelSet::subbass2: return kSpeakerLfe2;
default: break;
}
@@ -1163,29 +1231,29 @@ public:
{
switch (type)
{
case kSpeakerL: return AudioChannelSet::ChannelType::left;
case kSpeakerR: return AudioChannelSet::ChannelType::right;
case kSpeakerC: return AudioChannelSet::ChannelType::centre;
case kSpeakerLfe: return AudioChannelSet::ChannelType::subbass;
case kSpeakerLs: return AudioChannelSet::ChannelType::surroundLeft;
case kSpeakerRs: return AudioChannelSet::ChannelType::surroundRight;
case kSpeakerLc: return AudioChannelSet::ChannelType::centreLeft;
case kSpeakerRc: return AudioChannelSet::ChannelType::centreRight;
case kSpeakerS: return AudioChannelSet::ChannelType::surround;
case kSpeakerSl: return AudioChannelSet::ChannelType::sideLeft;
case kSpeakerSr: return AudioChannelSet::ChannelType::sideRight;
case kSpeakerTm: return AudioChannelSet::ChannelType::topMiddle;
case kSpeakerTfl: return AudioChannelSet::ChannelType::topFrontLeft;
case kSpeakerTfc: return AudioChannelSet::ChannelType::topFrontCentre;
case kSpeakerTfr: return AudioChannelSet::ChannelType::topFrontRight;
case kSpeakerTrl: return AudioChannelSet::ChannelType::topRearLeft;
case kSpeakerTrc: return AudioChannelSet::ChannelType::topRearCentre;
case kSpeakerTrr: return AudioChannelSet::ChannelType::topRearRight;
case kSpeakerLfe2: return AudioChannelSet::ChannelType::subbass2;
case kSpeakerL: return AudioChannelSet::left;
case kSpeakerR: return AudioChannelSet::right;
case kSpeakerC: return AudioChannelSet::centre;
case kSpeakerLfe: return AudioChannelSet::subbass;
case kSpeakerLs: return AudioChannelSet::surroundLeft;
case kSpeakerRs: return AudioChannelSet::surroundRight;
case kSpeakerLc: return AudioChannelSet::centreLeft;
case kSpeakerRc: return AudioChannelSet::centreRight;
case kSpeakerS: return AudioChannelSet::surround;
case kSpeakerSl: return AudioChannelSet::sideLeft;
case kSpeakerSr: return AudioChannelSet::sideRight;
case kSpeakerTm: return AudioChannelSet::topMiddle;
case kSpeakerTfl: return AudioChannelSet::topFrontLeft;
case kSpeakerTfc: return AudioChannelSet::topFrontCentre;
case kSpeakerTfr: return AudioChannelSet::topFrontRight;
case kSpeakerTrl: return AudioChannelSet::topRearLeft;
case kSpeakerTrc: return AudioChannelSet::topRearCentre;
case kSpeakerTrr: return AudioChannelSet::topRearRight;
case kSpeakerLfe2: return AudioChannelSet::subbass2;
default: break;
}
return AudioChannelSet::ChannelType::unknown;
return AudioChannelSet::unknown;
}
};
@@ -1249,25 +1317,6 @@ public:
if (hostWindow != 0)
checkWindowVisibilityVST (hostWindow, editorComp, useNSView);
#endif
tryMasterIdle();
}
void tryMasterIdle()
{
if (Component::isMouseButtonDownAnywhere() && ! recursionCheck)
{
const juce::uint32 now = juce::Time::getMillisecondCounter();
if (now > lastMasterIdleCall + 20 && editorComp != nullptr)
{
lastMasterIdleCall = now;
recursionCheck = true;
masterIdle();
recursionCheck = false;
}
}
}
void doIdleCallback()
@@ -1276,7 +1325,7 @@ public:
if (MessageManager::getInstance()->isThisTheMessageThread()
&& ! recursionCheck)
{
recursionCheck = true;
ScopedValueSetter<bool> svs (recursionCheck, true, false);
JUCE_AUTORELEASEPOOL
{
@@ -1285,8 +1334,6 @@ public:
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
if (ComponentPeer* p = ComponentPeer::getPeer(i))
p->performAnyPendingRepaintsNow();
recursionCheck = false;
}
}
}
@@ -1322,7 +1369,7 @@ public:
PopupMenu::dismissAllActiveMenus();
jassert (! recursionCheck);
recursionCheck = true;
ScopedValueSetter<bool> svs (recursionCheck, true, false);
if (editorComp != nullptr)
{
@@ -1333,7 +1380,6 @@ public:
if (canDeleteLaterIfModal)
{
shouldDeleteEditor = true;
recursionCheck = false;
return;
}
}
@@ -1358,8 +1404,6 @@ public:
#if JUCE_LINUX
hostWindow = 0;
#endif
recursionCheck = false;
}
}
@@ -1422,7 +1466,7 @@ public:
{
editorSize.left = 0;
editorSize.top = 0;
editorSize.right = (VstInt16) editorComp->getWidth();
editorSize.right = (VstInt16) editorComp->getWidth();
editorSize.bottom = (VstInt16) editorComp->getHeight();
*((ERect**) ptr) = &editorSize;
@@ -1515,8 +1559,7 @@ public:
//==============================================================================
// A component to hold the AudioProcessorEditor, and cope with some housekeeping
// chores when it changes or repaints.
class EditorCompWrapper : public Component,
public AsyncUpdater
class EditorCompWrapper : public Component
{
public:
EditorCompWrapper (JuceVSTWrapper& w, AudioProcessorEditor* editor)
@@ -1533,6 +1576,8 @@ public:
if (! getHostType().isReceptor())
addMouseListener (this, true);
#endif
ignoreUnused (fakeMouseGenerator);
}
~EditorCompWrapper()
@@ -1543,15 +1588,6 @@ public:
void paint (Graphics&) override {}
void paintOverChildren (Graphics&) override
{
// this causes an async call to masterIdle() to help
// creaky old DAWs like Nuendo repaint themselves while we're
// repainting. Otherwise they just seem to give up and sit there
// waiting.
triggerAsyncUpdate();
}
#if JUCE_MAC
bool keyPressed (const KeyPress&) override
{
@@ -1605,11 +1641,6 @@ public:
}
}
void handleAsyncUpdate() override
{
wrapper.tryMasterIdle();
}
#if JUCE_WINDOWS
void mouseDown (const MouseEvent&) override
{
@@ -1710,7 +1741,7 @@ private:
if (filter != nullptr)
{
int numChannels = filter->getTotalNumInputChannels() + filter->getTotalNumOutputChannels();
int numChannels = cEffect.numInputs + cEffect.numOutputs;
tmpBuffers.tempChannels.insertMultiple (0, nullptr, numChannels);
}
}
@@ -1721,6 +1752,29 @@ private:
deleteTempChannels (doubleTempBuffers);
}
//==============================================================================
void resetAuxChannelsToDefaultLayout (bool isInput) const
{
// set side-chain and aux channels to their default layout
for (int busIdx = 1; busIdx < busUtils.getBusCount (isInput); ++busIdx)
{
bool success = filter->setPreferredBusArrangement (isInput, busIdx, busUtils.getDefaultLayoutForBus (isInput, busIdx));
// VST 2 only supports a static channel layout on aux/sidechain channels
// You must at least support the default layout regardless of the layout of the main bus.
// If this is a problem for your plug-in, then consider using VST-3.
jassert (success);
ignoreUnused (success);
}
}
bool hostOnlySupportsStereo () const
{
const PluginHostType host (getHostType ());
// there are probably more hosts that need listing here
return host.isAbletonLive();
}
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceVSTWrapper)
};


+ 7
- 5
libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm View File

@@ -34,9 +34,6 @@
#include "../utility/juce_FakeMouseMoveGenerator.h"
#include "../utility/juce_CarbonVisibility.h"
#undef Component
#undef Point
//==============================================================================
namespace juce
{
@@ -66,6 +63,11 @@ static pascal OSStatus viewBoundsChangedEvent (EventHandlerCallRef, EventRef, vo
updateEditorCompBoundsVST ((Component*) user);
return noErr;
}
static bool shouldManuallyCloseHostWindow()
{
return getHostType().isCubase7orLater() || getHostType().isRenoise();
}
#endif
//==============================================================================
@@ -87,7 +89,7 @@ void* attachComponentToWindowRefVST (Component* comp, void* parentWindowOrView,
{
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: parentWindowOrView];
if (getHostType().isCubase7orLater())
if (shouldManuallyCloseHostWindow())
{
[hostWindow setReleasedWhenClosed: NO];
}
@@ -212,7 +214,7 @@ void detachComponentFromWindowRefVST (Component* comp, void* window, bool isNSVi
comp->removeFromDesktop();
[pluginView release];
if (getHostType().isCubase7orLater())
if (shouldManuallyCloseHostWindow())
[hostWindow close];
else
[hostWindow release];


+ 12
- 7
libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -38,6 +38,10 @@
#define JUCE_VST3_CAN_REPLACE_VST2 1
#endif
#ifndef JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS
#define JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS 1
#endif
#if JUCE_VST3_CAN_REPLACE_VST2
#if JUCE_MSVC
#pragma warning (push)
@@ -51,9 +55,6 @@
#endif
#endif
#undef Point
#undef Component
namespace juce
{
@@ -480,9 +481,11 @@ private:
parameters.addParameter (new BypassParam (*pluginInstance, numParameters));
}
// We need to account for the bypass parameter in the numParameters passed to
// the next function
#if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS
// (NB: the +1 is to account for the bypass parameter)
initialiseMidiControllerMappings (pluginInstance->getNumParameters() + 1);
#endif
audioProcessorChanged (pluginInstance);
}
}
@@ -639,7 +642,7 @@ private:
private:
//==============================================================================
class ContentWrapperComponent : public juce::Component
class ContentWrapperComponent : public Component
{
public:
ContentWrapperComponent (JuceVST3Editor& editor, AudioProcessor& plugin)
@@ -1569,11 +1572,13 @@ public:
const int id = (int) paramQueue->getParameterId();
if (isPositiveAndBelow (id, pluginInstance->getNumParameters()))
pluginInstance->setParameter (id, (float) value);
pluginInstance->setParameter (id, static_cast<float> (value));
else if (id == vstBypassParameterId)
setBypassed (static_cast<float> (value) != 0.0f);
#if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS
else
addParameterChangeToMidiBuffer (offsetSamples, id, value);
#endif
}
}
}


+ 0
- 1
libs/juce/source/modules/juce_audio_plugin_client/juce_audio_plugin_client.h View File

@@ -28,7 +28,6 @@
#include "../juce_gui_basics/juce_gui_basics.h"
#include "../juce_audio_basics/juce_audio_basics.h"
#include "../juce_audio_processors/juce_audio_processors.h"
#include "utility/juce_CheckSettingMacros.h"
namespace juce
{


+ 5
- 4
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h View File

@@ -31,6 +31,11 @@
#error "You need to enable at least one plugin format!"
#endif
#ifdef JUCE_CHECKSETTINGMACROS_H
#error "This header should never be included twice! Otherwise something is wrong."
#endif
#define JUCE_CHECKSETTINGMACROS_H
#ifndef JucePlugin_IsSynth
#error "You need to define the JucePlugin_IsSynth value!"
#endif
@@ -55,10 +60,6 @@
#error "JucePlugin_Latency is now deprecated - instead, call the AudioProcessor::setLatencySamples() method if your plugin has a non-zero delay"
#endif
#ifndef JucePlugin_SilenceInProducesSilenceOut
#error "You need to define the JucePlugin_SilenceInProducesSilenceOut value!"
#endif
#ifndef JucePlugin_EditorRequiresKeyboardFocus
#error "You need to define the JucePlugin_EditorRequiresKeyboardFocus value!"
#endif


+ 5
- 5
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h View File

@@ -31,12 +31,12 @@ using namespace juce;
namespace juce
{
#if JUCE_MAC
#define Point juce::Point
#define Component juce::Component
#define Component juce::Component
void repostCurrentNSEvent();
#endif
#if JUCE_MAC
#define Point juce::Point
void repostCurrentNSEvent();
#endif
//==============================================================================
inline const PluginHostType& getHostType()


+ 0
- 9
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h View File

@@ -50,23 +50,14 @@
#define JUCE_SUPPORT_CARBON 1
#endif
#define Point CarbonDummyPointName
#if JUCE_SUPPORT_CARBON
#define Component CarbonDummyCompName
#endif
#ifdef __OBJC__
#include <Cocoa/Cocoa.h>
#endif
#if JUCE_SUPPORT_CARBON
#include <Carbon/Carbon.h>
#undef Component
#endif
#undef Point
#include <objc/runtime.h>
#include <objc/objc.h>
#include <objc/message.h>


+ 16
- 2
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginBusUtilities.h View File

@@ -72,6 +72,15 @@ struct PluginBusUtilities
return nullptr;
}
int maxNumberOfChannels() const noexcept
{
int maxChannels = 0;
for (int i = 0; i < supportedLayouts.size(); ++i)
maxChannels = jmax (maxChannels, supportedLayouts.getReference (i).size());
return maxChannels;
}
int defaultLayoutIndex;
bool busIgnoresLayout, canBeDisabled, isEnabledByDefault;
SortedSet<AudioChannelSet> supportedLayouts;
@@ -88,12 +97,12 @@ struct PluginBusUtilities
bool hasOutputs (int bus) const noexcept { return isBusEnabled (false, bus); }
int getNumEnabledBuses (bool inputBus) const noexcept { int i; for (i = 0; i < getBusCount (inputBus); ++i) if (! isBusEnabled (inputBus, i)) break; return i; }
int findTotalNumChannels (bool isInput) const noexcept
int findTotalNumChannels (bool isInput, int busOffset = 0) const noexcept
{
int total = 0;
const AudioBusArray& ioBuses = getFilterBus (isInput);
for (int i = 0; i < ioBuses.size(); ++i)
for (int i = busOffset; i < ioBuses.size(); ++i)
total += ioBuses.getReference (i).channels.size();
return total;
@@ -341,7 +350,11 @@ private:
case 2:
sets.add (AudioChannelSet::stereo());
break;
case 3:
sets.add (AudioChannelSet::createLCR());
break;
case 4:
sets.add (AudioChannelSet::createLCRS());
sets.add (AudioChannelSet::quadraphonic());
sets.add (AudioChannelSet::ambisonic());
break;
@@ -351,6 +364,7 @@ private:
break;
case 6:
sets.add (AudioChannelSet::hexagonal());
sets.add (AudioChannelSet::create5point1());
sets.add (AudioChannelSet::create6point0());
break;
case 7:


+ 31
- 25
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h View File

@@ -53,6 +53,7 @@ public:
MergingPyramix,
MuseReceptorGeneric,
Reaper,
Renoise,
SteinbergCubase4,
SteinbergCubase5,
SteinbergCubase5Bridged,
@@ -80,31 +81,33 @@ public:
HostType type;
//==============================================================================
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8 || type == AbletonLiveGeneric; }
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
bool isArdour() const noexcept { return type == Ardour; }
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6 || type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubaseGeneric; }
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
bool isLogic() const noexcept { return type == AppleLogic; }
bool isFinalCut() const noexcept { return type == FinalCut; }
bool isFruityLoops() const noexcept { return type == FruityLoops; }
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
bool isPremiere() const noexcept { return type == AdobePremierePro; }
bool isPyramix() const noexcept { return type == MergingPyramix; }
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
bool isReaper() const noexcept { return type == Reaper; }
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric; }
bool isSteinbergTestHost() const noexcept{ return type == SteinbergTestHost; }
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
bool isStudioOne() const noexcept { return type == StudioOne; }
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric; }
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
bool isWaveBurner() const noexcept { return type == WaveBurner; }
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8 || type == AbletonLiveGeneric; }
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
bool isArdour() const noexcept { return type == Ardour; }
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6 || type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubaseGeneric; }
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
bool isLogic() const noexcept { return type == AppleLogic; }
bool isFinalCut() const noexcept { return type == FinalCut; }
bool isFruityLoops() const noexcept { return type == FruityLoops; }
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
bool isPremiere() const noexcept { return type == AdobePremierePro; }
bool isPyramix() const noexcept { return type == MergingPyramix; }
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
bool isReaper() const noexcept { return type == Reaper; }
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric; }
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
bool isStudioOne() const noexcept { return type == StudioOne; }
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric; }
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
bool isWaveBurner() const noexcept { return type == WaveBurner; }
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
bool isRenoise() const noexcept { return type == Renoise; }
bool isProTools() const noexcept { return type == DigidesignProTools; }
//==============================================================================
const char* getHostDescription() const noexcept
@@ -128,6 +131,7 @@ public:
case MergingPyramix: return "Pyramix";
case MuseReceptorGeneric: return "Muse Receptor";
case Reaper: return "Reaper";
case Renoise: return "Renoise";
case SteinbergCubase4: return "Steinberg Cubase 4";
case SteinbergCubase5: return "Steinberg Cubase 5";
case SteinbergCubase5Bridged: return "Steinberg Cubase 5 Bridged";
@@ -198,6 +202,7 @@ private:
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
#elif JUCE_WINDOWS
if (hostFilename.containsIgnoreCase ("Live 6.")) return AbletonLive6;
@@ -235,6 +240,7 @@ private:
if (hostFilename.containsIgnoreCase ("VST_Scanner")) return VBVSTScanner;
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
#elif JUCE_LINUX
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;


+ 0
- 1
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp View File

@@ -27,7 +27,6 @@
#endif
#include "../../juce_core/system/juce_TargetPlatform.h"
#include "../utility/juce_CheckSettingMacros.h"
#include "juce_IncludeModuleHeaders.h"
#if _MSC_VER || JUCE_MINGW


+ 0
- 5
libs/juce/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -387,11 +387,6 @@ public:
void* getPlatformSpecificData() override { return audioUnit; }
const String getName() const override { return pluginName; }
bool silenceInProducesSilenceOut() const override
{
return getTailLengthSeconds() <= 0;
}
double getTailLengthSeconds() const override
{
Float64 tail = 0;


+ 0
- 1
libs/juce/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp View File

@@ -252,7 +252,6 @@ public:
bool acceptsMidi() const { return false; }
bool producesMidi() const { return false; }
bool silenceInProducesSilenceOut() const { return plugin == nullptr; } // ..any way to get a proper answer for these?
double getTailLengthSeconds() const { return 0.0; }
//==============================================================================


+ 39
- 39
libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3Common.h View File

@@ -143,25 +143,25 @@ static inline Steinberg::Vst::Speaker getSpeakerType (AudioChannelSet::ChannelTy
switch (type)
{
case AudioChannelSet::ChannelType::left: return kSpeakerL;
case AudioChannelSet::ChannelType::right: return kSpeakerR;
case AudioChannelSet::ChannelType::centre: return kSpeakerC;
case AudioChannelSet::ChannelType::subbass: return kSpeakerLfe;
case AudioChannelSet::ChannelType::surroundLeft: return kSpeakerLs;
case AudioChannelSet::ChannelType::surroundRight: return kSpeakerRs;
case AudioChannelSet::ChannelType::centreLeft: return kSpeakerLc;
case AudioChannelSet::ChannelType::centreRight: return kSpeakerRc;
case AudioChannelSet::ChannelType::surround: return kSpeakerS;
case AudioChannelSet::ChannelType::sideLeft: return kSpeakerSl;
case AudioChannelSet::ChannelType::sideRight: return kSpeakerSr;
case AudioChannelSet::ChannelType::topMiddle: return kSpeakerTm;
case AudioChannelSet::ChannelType::topFrontLeft: return kSpeakerTfl;
case AudioChannelSet::ChannelType::topFrontCentre: return kSpeakerTfc;
case AudioChannelSet::ChannelType::topFrontRight: return kSpeakerTfr;
case AudioChannelSet::ChannelType::topRearLeft: return kSpeakerTrl;
case AudioChannelSet::ChannelType::topRearCentre: return kSpeakerTrc;
case AudioChannelSet::ChannelType::topRearRight: return kSpeakerTrr;
case AudioChannelSet::ChannelType::subbass2: return kSpeakerLfe2;
case AudioChannelSet::left: return kSpeakerL;
case AudioChannelSet::right: return kSpeakerR;
case AudioChannelSet::centre: return kSpeakerC;
case AudioChannelSet::subbass: return kSpeakerLfe;
case AudioChannelSet::surroundLeft: return kSpeakerLs;
case AudioChannelSet::surroundRight: return kSpeakerRs;
case AudioChannelSet::centreLeft: return kSpeakerLc;
case AudioChannelSet::centreRight: return kSpeakerRc;
case AudioChannelSet::surround: return kSpeakerS;
case AudioChannelSet::sideLeft: return kSpeakerSl;
case AudioChannelSet::sideRight: return kSpeakerSr;
case AudioChannelSet::topMiddle: return kSpeakerTm;
case AudioChannelSet::topFrontLeft: return kSpeakerTfl;
case AudioChannelSet::topFrontCentre: return kSpeakerTfc;
case AudioChannelSet::topFrontRight: return kSpeakerTfr;
case AudioChannelSet::topRearLeft: return kSpeakerTrl;
case AudioChannelSet::topRearCentre: return kSpeakerTrc;
case AudioChannelSet::topRearRight: return kSpeakerTrr;
case AudioChannelSet::subbass2: return kSpeakerLfe2;
default: break;
}
@@ -174,29 +174,29 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak
switch (type)
{
case kSpeakerL: return AudioChannelSet::ChannelType::left;
case kSpeakerR: return AudioChannelSet::ChannelType::right;
case kSpeakerC: return AudioChannelSet::ChannelType::centre;
case kSpeakerLfe: return AudioChannelSet::ChannelType::subbass;
case kSpeakerLs: return AudioChannelSet::ChannelType::surroundLeft;
case kSpeakerRs: return AudioChannelSet::ChannelType::surroundRight;
case kSpeakerLc: return AudioChannelSet::ChannelType::centreLeft;
case kSpeakerRc: return AudioChannelSet::ChannelType::centreRight;
case kSpeakerS: return AudioChannelSet::ChannelType::surround;
case kSpeakerSl: return AudioChannelSet::ChannelType::sideLeft;
case kSpeakerSr: return AudioChannelSet::ChannelType::sideRight;
case kSpeakerTm: return AudioChannelSet::ChannelType::topMiddle;
case kSpeakerTfl: return AudioChannelSet::ChannelType::topFrontLeft;
case kSpeakerTfc: return AudioChannelSet::ChannelType::topFrontCentre;
case kSpeakerTfr: return AudioChannelSet::ChannelType::topFrontRight;
case kSpeakerTrl: return AudioChannelSet::ChannelType::topRearLeft;
case kSpeakerTrc: return AudioChannelSet::ChannelType::topRearCentre;
case kSpeakerTrr: return AudioChannelSet::ChannelType::topRearRight;
case kSpeakerLfe2: return AudioChannelSet::ChannelType::subbass2;
case kSpeakerL: return AudioChannelSet::left;
case kSpeakerR: return AudioChannelSet::right;
case kSpeakerC: return AudioChannelSet::centre;
case kSpeakerLfe: return AudioChannelSet::subbass;
case kSpeakerLs: return AudioChannelSet::surroundLeft;
case kSpeakerRs: return AudioChannelSet::surroundRight;
case kSpeakerLc: return AudioChannelSet::centreLeft;
case kSpeakerRc: return AudioChannelSet::centreRight;
case kSpeakerS: return AudioChannelSet::surround;
case kSpeakerSl: return AudioChannelSet::sideLeft;
case kSpeakerSr: return AudioChannelSet::sideRight;
case kSpeakerTm: return AudioChannelSet::topMiddle;
case kSpeakerTfl: return AudioChannelSet::topFrontLeft;
case kSpeakerTfc: return AudioChannelSet::topFrontCentre;
case kSpeakerTfr: return AudioChannelSet::topFrontRight;
case kSpeakerTrl: return AudioChannelSet::topRearLeft;
case kSpeakerTrc: return AudioChannelSet::topRearCentre;
case kSpeakerTrr: return AudioChannelSet::topRearRight;
case kSpeakerLfe2: return AudioChannelSet::subbass2;
default: break;
}
return AudioChannelSet::ChannelType::unknown;
return AudioChannelSet::unknown;
}
static inline Steinberg::Vst::SpeakerArrangement getSpeakerArrangement (const AudioChannelSet& channels) noexcept


+ 0
- 8
libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h View File

@@ -25,9 +25,6 @@
#ifndef JUCE_VST3HEADERS_H_INCLUDED
#define JUCE_VST3HEADERS_H_INCLUDED
#undef Point
#undef Component
// Wow, those Steinberg guys really don't worry too much about compiler warnings.
#if _MSC_VER
#pragma warning (disable: 4505)
@@ -85,8 +82,6 @@
#if JUCE_MINGW
#define _set_abort_behavior(...)
#endif
#define Point CarbonDummyPointName // The VST headers include some system headers that need
// to match the name our hacky Carbon workaround used.
#include <base/source/baseiids.cpp>
#include <base/source/fatomic.cpp>
#include <base/source/fbuffer.cpp>
@@ -112,7 +107,6 @@
#include <public.sdk/source/vst/vstcomponentbase.cpp>
#include <public.sdk/source/vst/vstparameters.cpp>
#include <public.sdk/source/vst/hosting/hostclasses.cpp>
#undef Point
//==============================================================================
namespace Steinberg
@@ -177,7 +171,5 @@ namespace Steinberg
#undef DEF_CLASS2
#undef DEF_CLASS_W
#undef END_FACTORY
#undef Point
#undef Component
#endif // JUCE_VST3HEADERS_H_INCLUDED

+ 3
- 11
libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -1861,23 +1861,15 @@ public:
bool producesMidi() const override { return getBusInfo (false, false).channelCount > 0; }
//==============================================================================
bool silenceInProducesSilenceOut() const override
{
if (processor != nullptr)
return processor->getTailSamples() == Vst::kNoTail;
return true;
}
/** May return a negative value as a means of informing us that the plugin has "infinite tail," or 0 for "no tail." */
double getTailLengthSeconds() const override
{
if (processor != nullptr)
{
const double currentSampleRate = getSampleRate();
const double sampleRate = getSampleRate();
if (currentSampleRate > 0.0)
return jlimit (0, 0x7fffffff, (int) processor->getTailSamples()) / currentSampleRate;
if (sampleRate > 0.0)
return jlimit (0, 0x7fffffff, (int) processor->getTailSamples()) / sampleRate;
}
return 0.0;


+ 5
- 10
libs/juce/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -890,23 +890,18 @@ public:
return uid;
}
bool silenceInProducesSilenceOut() const override
{
return effect == nullptr || (effect->flags & effFlagsNoSoundInStop) != 0;
}
double getTailLengthSeconds() const override
{
if (effect == nullptr)
return 0.0;
const double currentSampleRate = getSampleRate();
const double sampleRate = getSampleRate();
if (currentSampleRate <= 0)
if (sampleRate <= 0)
return 0.0;
VstIntPtr samples = dispatch (effGetTailSize, 0, 0, 0, 0);
return samples / currentSampleRate;
return samples / sampleRate;
}
bool acceptsMidi() const override { return wantsMidiMessages; }
@@ -2915,11 +2910,11 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch()
const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName());
FileSearchPath paths;
paths.add (WindowsRegistry::getValue ("HKLM\\Software\\VST\\VSTPluginsPath",
paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath",
programFiles + "\\Steinberg\\VstPlugins"));
paths.removeNonExistentPaths();
paths.add (WindowsRegistry::getValue ("HKLM\\Software\\VST\\VSTPluginsPath",
paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath",
programFiles + "\\VstPlugins"));
return paths;
#endif


+ 2
- 5
libs/juce/source/modules/juce_audio_processors/juce_audio_processors.cpp View File

@@ -31,7 +31,8 @@
#error "Incorrect use of JUCE cpp file"
#endif
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#include "juce_audio_processors.h"
#include "../juce_gui_extra/juce_gui_extra.h"
@@ -40,11 +41,7 @@
#if JUCE_SUPPORT_CARBON \
&& ((JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \
|| ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6))
#define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers)
#define Component CarbonDummyCompName
#include <Carbon/Carbon.h>
#undef Point
#undef Component
#endif
#endif


+ 3
- 3
libs/juce/source/modules/juce_audio_processors/juce_audio_processors.h View File

@@ -29,7 +29,7 @@
#include "../juce_audio_basics/juce_audio_basics.h"
//=============================================================================
//==============================================================================
/** Config: JUCE_PLUGINHOST_VST
Enables the VST audio plugin hosting classes. This requires the Steinberg VST SDK to be
installed on your machine.
@@ -67,8 +67,8 @@
#define JUCE_SUPPORT_CARBON 1
#endif
//=============================================================================
//=============================================================================
//==============================================================================
//==============================================================================
namespace juce
{


+ 18
- 12
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp View File

@@ -28,8 +28,11 @@ bool AudioChannelSet::operator== (const AudioChannelSet& other) const noexcept
bool AudioChannelSet::operator!= (const AudioChannelSet& other) const noexcept { return channels != other.channels; }
bool AudioChannelSet::operator< (const AudioChannelSet& other) const noexcept { return channels < other.channels; }
const char* AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) noexcept
String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type)
{
if (type >= discreteChannel0)
return String ("Discrete ") + String (type - discreteChannel0 + 1);
switch (type)
{
case left: return NEEDS_TRANS("Left");
@@ -63,8 +66,11 @@ const char* AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType ty
return "Unknown";
}
const char* AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelType type) noexcept
String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelType type)
{
if (type >= discreteChannel0)
return String (type - discreteChannel0 + 1);
switch (type)
{
case left: return "L";
@@ -151,17 +157,17 @@ AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << sideLeft) | (1u << sideRight)); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << sideLeft) | (1u << sideRight) | (1u << centre)); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << sideLeft) | (1u << sideRight) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << sideLeft) | (1u << sideRight) | (1u << centre) | (1u << surround) | (1u << wideLeft) | (1u << wideRight)); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight)); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre)); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre) | (1u << surround) | (1u << wideLeft) | (1u << wideRight)); }
AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surroundLeft) | (1u << surroundRight)); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << surroundLeft) | (1u << surroundRight)); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surroundLeft) | (1u << surroundRight) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << surroundLeft) | (1u << surroundRight) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surroundLeft) | (1u << surroundRight) | (1u << topRearLeft) | (1u << topRearRight)); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << surroundLeft) | (1u << surroundRight) | (1u << topRearLeft) | (1u << topRearRight)); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight)); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight)); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight) | (1u << surroundLeft) | (1u << surroundRight)); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight) | (1u << surroundLeft) | (1u << surroundRight)); }
AudioChannelSet AudioChannelSet::createFront7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centreLeft) | (1u << centreRight)); }
AudioChannelSet AudioChannelSet::createFront7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centreLeft) | (1u << centreRight)); }


+ 2
- 2
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h View File

@@ -145,10 +145,10 @@ public:
};
/** Returns the name of a given channel type. For example, this method may return "Surround Left". */
static const char* getChannelTypeName (ChannelType) noexcept;
static String getChannelTypeName (ChannelType);
/** Returns the abbreviated name of a channel type. For example, this method may return "Ls". */
static const char* getAbbreviatedChannelTypeName (ChannelType) noexcept;
static String getAbbreviatedChannelTypeName (ChannelType);
//==============================================================================
/** Adds a channel to the set. */


+ 14
- 12
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp View File

@@ -32,7 +32,7 @@ void JUCE_CALLTYPE AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::Wrapp
AudioProcessor::AudioProcessor()
: wrapperType (wrapperTypeBeingCreated.get()),
playHead (nullptr),
sampleRate (0),
currentSampleRate (0),
blockSize (0),
latencySamples (0),
#if JUCE_DEBUG
@@ -42,23 +42,25 @@ AudioProcessor::AudioProcessor()
nonRealtime (false),
processingPrecision (singlePrecision)
{
#if ! JucePlugin_IsMidiEffect
#ifdef JucePlugin_PreferredChannelConfigurations
const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
#else
const short channelConfigs[][2] = { {2, 2} };
#endif
int numChannelConfigs = sizeof (channelConfigs) / sizeof (*channelConfigs);
if (numChannelConfigs > 0)
{
#if ! JucePlugin_IsSynth
busArrangement.inputBuses.add (AudioProcessorBus ("Input", AudioChannelSet::canonicalChannelSet (channelConfigs[0][0])));
#endif
busArrangement.outputBuses.add (AudioProcessorBus ("Output", AudioChannelSet::canonicalChannelSet (channelConfigs[0][1])));
}
#endif
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
busArrangement.inputBuses.add (AudioProcessorBus ("Input", AudioChannelSet::canonicalChannelSet (channelConfigs[0][0])));
#endif
busArrangement.outputBuses.add (AudioProcessorBus ("Output", AudioChannelSet::canonicalChannelSet (channelConfigs[0][1])));
#ifdef JucePlugin_PreferredChannelConfigurations
#if ! JucePlugin_IsSynth
AudioProcessor::setPreferredBusArrangement (true, 0, AudioChannelSet::stereo());
#endif
AudioProcessor::setPreferredBusArrangement (false, 0, AudioChannelSet::stereo());
#endif
#endif
updateSpeakerFormatStrings();
}
@@ -123,7 +125,7 @@ void AudioProcessor::setPlayConfigDetails (const int newNumIns,
void AudioProcessor::setRateAndBufferSizeDetails (double newSampleRate, int newBlockSize) noexcept
{
sampleRate = newSampleRate;
currentSampleRate = newSampleRate;
blockSize = newBlockSize;
}


+ 16
- 8
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h View File

@@ -317,6 +317,14 @@ public:
changing the channel layout of other buses, for example, if your plug-in requires the same
number of input and output channels.
For most basic plug-ins, which do not require side-chains, aux buses or detailed audio
channel layout information, it is easier to specify the acceptable channel configurations
via the "PlugIn Channel Configurations" field in the Introjucer. In this case, you should
not override this method.
If, on the other hand, you decide to override this method then you need to make sure that
"PlugIn Channel Configurations" field in the Introjucer is empty.
Note, that you must not do any heavy allocations or calculations in this callback as it may
be called several hundred times during initialization. If you require any layout specific
allocations then defer these to prepareToPlay callback.
@@ -423,7 +431,7 @@ public:
This can be called from your processBlock() method - it's not guaranteed
to be valid at any other time, and may return 0 if it's unknown.
*/
double getSampleRate() const noexcept { return sampleRate; }
double getSampleRate() const noexcept { return currentSampleRate; }
/** Returns the current typical block size that is being used.
@@ -453,9 +461,6 @@ public:
*/
void setLatencySamples (int newLatency);
/** Returns true if a silent input always produces a silent output. */
virtual bool silenceInProducesSilenceOut() const = 0;
/** Returns the length of the filter's tail, in seconds. */
virtual double getTailLengthSeconds() const = 0;
@@ -883,7 +888,7 @@ public:
//==============================================================================
/** This is called by the processor to specify its details before being played. Use this
version of the function if you are not interested in any sidechain or aux buses
version of the function if you are not interested in any sidechain and/or aux buses
and do not care about the layout of channels. Otherwise use setRateAndBufferSizeDetails.*/
void setPlayConfigDetails (int numIns, int numOuts, double sampleRate, int blockSize);
@@ -919,7 +924,7 @@ public:
WrapperType wrapperType;
//==============================================================================
#ifndef DOXYGEN
#ifndef DOXYGEN
/** Deprecated: use getTotalNumInputChannels instead. */
JUCE_DEPRECATED_WITH_BODY (int getNumInputChannels() const noexcept, { return getTotalNumInputChannels(); })
JUCE_DEPRECATED_WITH_BODY (int getNumOutputChannels() const noexcept, { return getTotalNumOutputChannels(); })
@@ -946,7 +951,7 @@ public:
the constructor. */
JUCE_DEPRECATED (virtual bool isInputChannelStereoPair (int index) const);
JUCE_DEPRECATED (virtual bool isOutputChannelStereoPair (int index) const);
#endif
#endif
//==============================================================================
/** Helper function that just converts an xml element into a binary blob.
@@ -982,7 +987,7 @@ private:
#if ! JUCE_AUDIO_PROCESSOR_NO_GUI
Component::SafePointer<AudioProcessorEditor> activeEditor;
#endif
double sampleRate;
double currentSampleRate;
int blockSize, latencySamples;
#if JUCE_DEBUG
bool textRecursionCheck;
@@ -1005,6 +1010,9 @@ private:
void disableNonMainBuses (bool isInput);
void updateSpeakerFormatStrings();
// This method is no longer used - you can delete it from your AudioProcessor classes.
JUCE_DEPRECATED_WITH_BODY (virtual bool silenceInProducesSilenceOut() const, { return false; });
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessor)
};


+ 0
- 6
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -1460,7 +1460,6 @@ void AudioProcessorGraph::processAudio (AudioBuffer<FloatType>& buffer, MidiBuff
midiMessages.addEvents (currentMidiOutputBuffer, 0, buffer.getNumSamples(), 0);
}
bool AudioProcessorGraph::silenceInProducesSilenceOut() const { return false; }
double AudioProcessorGraph::getTailLengthSeconds() const { return 0; }
bool AudioProcessorGraph::acceptsMidi() const { return true; }
bool AudioProcessorGraph::producesMidi() const { return true; }
@@ -1601,11 +1600,6 @@ void AudioProcessorGraph::AudioGraphIOProcessor::processBlock (AudioBuffer<doubl
processAudio (buffer, midiMessages);
}
bool AudioProcessorGraph::AudioGraphIOProcessor::silenceInProducesSilenceOut() const
{
return isOutput();
}
double AudioProcessorGraph::AudioGraphIOProcessor::getTailLengthSeconds() const
{
return 0;


+ 0
- 2
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -311,7 +311,6 @@ public:
void processBlock (AudioBuffer<double>&, MidiBuffer&) override;
bool supportsDoublePrecisionProcessing() const override;
bool silenceInProducesSilenceOut() const override;
double getTailLengthSeconds() const override;
bool acceptsMidi() const override;
bool producesMidi() const override;
@@ -356,7 +355,6 @@ public:
void setNonRealtime (bool) noexcept override;
void setPlayHead (AudioPlayHead*) override;
bool silenceInProducesSilenceOut() const override;
double getTailLengthSeconds() const override;
bool acceptsMidi() const override;
bool producesMidi() const override;


+ 14
- 17
libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp View File

@@ -50,14 +50,17 @@ void AudioParameterFloat::setValue (float newValue) { value
float AudioParameterFloat::getDefaultValue() const { return range.convertTo0to1 (defaultValue); }
int AudioParameterFloat::getNumSteps() const { return AudioProcessorParameterWithID::getNumSteps(); }
float AudioParameterFloat::getValueForText (const String& text) const { return range.convertTo0to1 (text.getFloatValue()); }
String AudioParameterFloat::getText (float v, int length) const { return String (range.convertFrom0to1 (v), 2).substring (0, length); }
AudioParameterFloat& AudioParameterFloat::operator= (float newValue)
String AudioParameterFloat::getText (float v, int length) const
{
const float normalisedValue = range.convertTo0to1 (newValue);
String asText (range.convertFrom0to1 (v), 2);
return length > 0 ? asText.substring (0, length) : asText;
}
if (value != normalisedValue)
setValueNotifyingHost (normalisedValue);
AudioParameterFloat& AudioParameterFloat::operator= (float newValue)
{
if (value != newValue)
setValueNotifyingHost (range.convertTo0to1 (newValue));
return *this;
}
@@ -87,10 +90,8 @@ String AudioParameterInt::getText (float v, int /*length*/) const { retur
AudioParameterInt& AudioParameterInt::operator= (int newValue)
{
const float normalisedValue = convertTo0to1 (newValue);
if (value != normalisedValue)
setValueNotifyingHost (normalisedValue);
if (get() != newValue)
setValueNotifyingHost (convertTo0to1 (newValue));
return *this;
}
@@ -115,10 +116,8 @@ String AudioParameterBool::getText (float v, int /*length*/) const { retur
AudioParameterBool& AudioParameterBool::operator= (bool newValue)
{
const float normalisedValue = newValue ? 1.0f : 0.0f;
if (value != normalisedValue)
setValueNotifyingHost (normalisedValue);
if (get() != newValue)
setValueNotifyingHost (newValue ? 1.0f : 0.0f);
return *this;
}
@@ -148,10 +147,8 @@ String AudioParameterChoice::getText (float v, int /*length*/) const { retur
AudioParameterChoice& AudioParameterChoice::operator= (int newValue)
{
const float normalisedValue = convertTo0to1 (newValue);
if (value != normalisedValue)
setValueNotifyingHost (normalisedValue);
if (getIndex() != newValue)
setValueNotifyingHost (convertTo0to1 (newValue));
return *this;
}

+ 6
- 6
libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp View File

@@ -258,21 +258,21 @@ void AudioProcessorValueTreeState::updateParameterConnectionsToChildTrees()
}
}
void AudioProcessorValueTreeState::valueTreePropertyChanged (ValueTree&, const Identifier& property)
void AudioProcessorValueTreeState::valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (property == idPropertyID)
if (property == idPropertyID && tree.hasType (valueType) && tree.getParent() == state)
updateParameterConnectionsToChildTrees();
}
void AudioProcessorValueTreeState::valueTreeChildAdded (ValueTree& parent, ValueTree&)
void AudioProcessorValueTreeState::valueTreeChildAdded (ValueTree& parent, ValueTree& tree)
{
if (parent == state)
if (parent == state && tree.hasType (valueType))
updateParameterConnectionsToChildTrees();
}
void AudioProcessorValueTreeState::valueTreeChildRemoved (ValueTree& parent, ValueTree&, int)
void AudioProcessorValueTreeState::valueTreeChildRemoved (ValueTree& parent, ValueTree& tree, int)
{
if (parent == state)
if (parent == state && tree.hasType (valueType))
updateParameterConnectionsToChildTrees();
}


+ 1
- 1
libs/juce/source/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h View File

@@ -112,7 +112,7 @@ public:
*/
void getChannelAsPath (Path& result, const Range<float>* levels, int numLevels, int nextSample);
//==========================================================================
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 7
- 0
libs/juce/source/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp View File

@@ -270,6 +270,13 @@ int MidiKeyboardComponent::getKeyStartPosition (const int midiNoteNumber) const
return x;
}
int MidiKeyboardComponent::getTotalKeyboardWidth() const noexcept
{
int x, w;
getKeyPos (rangeEnd, x, w);
return x + w;
}
int MidiKeyboardComponent::getNoteAtPosition (Point<int> p)
{
float v;


+ 3
- 0
libs/juce/source/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h View File

@@ -209,6 +209,9 @@ public:
*/
int getKeyStartPosition (int midiNoteNumber) const;
/** Returns the total width needed to fit all the keys in the available range. */
int getTotalKeyboardWidth() const noexcept;
/** Returns the key at a given coordinate. */
int getNoteAtPosition (Point<int> position);


+ 3
- 2
libs/juce/source/modules/juce_audio_utils/juce_audio_utils.cpp View File

@@ -31,7 +31,9 @@
#error "Incorrect use of JUCE cpp file"
#endif
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#define JUCE_CORE_INCLUDE_JNI_HELPERS 1
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#include "juce_audio_utils.h"
namespace juce
@@ -54,7 +56,6 @@ namespace juce
#elif JUCE_IOS
#include "native/juce_ios_BluetoothMidiDevicePairingDialogue.mm"
#elif JUCE_ANDROID
#include "../juce_core/native/juce_android_JNIHelpers.h"
#include "native/juce_android_BluetoothMidiDevicePairingDialogue.cpp"
#elif JUCE_LINUX
#include "native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp"


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

@@ -30,7 +30,7 @@
#include "../juce_audio_formats/juce_audio_formats.h"
#include "../juce_audio_processors/juce_audio_processors.h"
//=============================================================================
//==============================================================================
namespace juce
{


+ 19
- 10
libs/juce/source/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp View File

@@ -64,7 +64,7 @@ struct AndroidBluetoothMidiInterface
return retval;
}
//==========================================================================
//==============================================================================
static bool pairBluetoothMidiDevice (const String& bluetoothAddress)
{
JNIEnv* env = getEnv();
@@ -90,7 +90,7 @@ struct AndroidBluetoothMidiInterface
javaString (bluetoothAddress).get());
}
//==========================================================================
//==============================================================================
static String getHumanReadableStringForBluetoothAddress (const String& address)
{
JNIEnv* env = getEnv();
@@ -111,7 +111,7 @@ struct AndroidBluetoothMidiInterface
return juceString (string);
}
//==========================================================================
//==============================================================================
static bool isBluetoothDevicePaired (const String& address)
{
JNIEnv* env = getEnv();
@@ -166,7 +166,7 @@ class AndroidBluetoothMidiDevicesListBox : public ListBox,
private Timer
{
public:
//==========================================================================
//==============================================================================
AndroidBluetoothMidiDevicesListBox()
: timerPeriodInMs (1000)
{
@@ -184,7 +184,7 @@ public:
}
private:
//==========================================================================
//==============================================================================
typedef AndroidBluetoothMidiDevice::ConnectionStatus DeviceStatus;
int getNumRows() override
@@ -226,7 +226,7 @@ private:
}
}
//==========================================================================
//==============================================================================
static Colour getDeviceNameFontColour (DeviceStatus deviceStatus) noexcept
{
if (deviceStatus == AndroidBluetoothMidiDevice::offline)
@@ -261,7 +261,7 @@ private:
return "Status unknown";
}
//==========================================================================
//==============================================================================
void listBoxItemClicked (int row, const MouseEvent&) override
{
const AndroidBluetoothMidiDevice& device = devices.getReference (row);
@@ -278,7 +278,7 @@ private:
updateDeviceList();
}
//==========================================================================
//==============================================================================
struct PairDeviceThread : public Thread,
private AsyncUpdater
{
@@ -310,7 +310,7 @@ private:
Component::SafePointer<AndroidBluetoothMidiDevicesListBox> owner;
};
//==========================================================================
//==============================================================================
void disconnectedDeviceClicked (int row)
{
stopTimer();
@@ -332,7 +332,7 @@ private:
AndroidBluetoothMidiInterface::unpairBluetoothMidiDevice (device.bluetoothAddress);
}
//==========================================================================
//==============================================================================
void updateDeviceList()
{
StringArray bluetoothAddresses = AndroidBluetoothMidiInterface::getBluetoothMidiDevicesNearby();
@@ -427,6 +427,15 @@ private:
//==============================================================================
bool BluetoothMidiDevicePairingDialogue::open()
{
if (! RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi))
{
// If you hit this assert, you probably forgot to get RuntimePermissions::bluetoothMidi.
// This is not going to work, boo! The pairing dialogue won't be able to scan for or
// find any devices, it will just display an empty list, so don't bother opening it.
jassertfalse;
return false;
}
BluetoothMidiSelectorOverlay* overlay = new BluetoothMidiSelectorOverlay;
return true;
}


+ 7
- 0
libs/juce/source/modules/juce_core/containers/juce_HashMap.h View File

@@ -424,6 +424,13 @@ public:
return entry != nullptr ? entry->value : ValueType();
}
/** Resets the iterator to its starting position. */
void reset() noexcept
{
entry = nullptr;
index = 0;
}
private:
//==============================================================================
const HashMap& hashMap;


+ 62
- 22
libs/juce/source/modules/juce_core/files/juce_File.cpp View File

@@ -70,8 +70,24 @@ File& File::operator= (File&& other) noexcept
const File File::nonexistent;
//==============================================================================
static String removeEllipsis (const String& path)
{
StringArray toks;
toks.addTokens (path, File::separatorString, StringRef());
for (int i = 1; i < toks.size(); ++i)
{
if (toks[i] == ".." && toks[i - 1] != "..")
{
toks.removeRange (i - 1, 2);
i = jmax (0, i - 2);
}
}
return toks.joinIntoString (File::separatorString);
}
String File::parseAbsolutePath (const String& p)
{
if (p.isEmpty())
@@ -81,6 +97,9 @@ String File::parseAbsolutePath (const String& p)
// Windows..
String path (p.replaceCharacter ('/', '\\'));
if (path.contains ("\\..\\"))
path = removeEllipsis (path);
if (path.startsWithChar (separator))
{
if (path[1] != separator)
@@ -120,6 +139,9 @@ String File::parseAbsolutePath (const String& p)
String path (p);
if (path.contains ("/../"))
path = removeEllipsis (path);
if (path.startsWithChar ('~'))
{
if (path[1] == separator || path[1] == 0)
@@ -347,62 +369,69 @@ int64 File::hashCode64() const { return fullPath.hashCode64(); }
//==============================================================================
bool File::isAbsolutePath (StringRef path)
{
return path.text[0] == separator
const juce_wchar firstChar = *(path.text);
return firstChar == separator
#if JUCE_WINDOWS
|| (path.isNotEmpty() && path.text[1] == ':');
|| (firstChar != 0 && path.text[1] == ':');
#else
|| path.text[0] == '~';
|| firstChar == '~';
#endif
}
File File::getChildFile (StringRef relativePath) const
{
if (isAbsolutePath (relativePath))
return File (String (relativePath.text));
String::CharPointerType r = relativePath.text;
if (relativePath[0] != '.')
return File (addTrailingSeparator (fullPath) + relativePath);
if (isAbsolutePath (r))
return File (String (r));
String path (fullPath);
// It's relative, so remove any ../ or ./ bits at the start..
#if JUCE_WINDOWS
if (relativePath.text.indexOf ((juce_wchar) '/') >= 0)
return getChildFile (String (relativePath.text).replaceCharacter ('/', '\\'));
if (r.indexOf ((juce_wchar) '/') >= 0)
return getChildFile (String (r).replaceCharacter ('/', '\\'));
#endif
while (relativePath[0] == '.')
String path (fullPath);
while (*r == '.')
{
const juce_wchar secondChar = relativePath[1];
String::CharPointerType lastPos = r;
const juce_wchar secondChar = *++r;
if (secondChar == '.')
if (secondChar == '.') // remove "../"
{
const juce_wchar thirdChar = relativePath[2];
const juce_wchar thirdChar = *++r;
if (thirdChar == 0 || thirdChar == separator)
if (thirdChar == separator || thirdChar == 0)
{
const int lastSlash = path.lastIndexOfChar (separator);
if (lastSlash >= 0)
path = path.substring (0, lastSlash);
relativePath = relativePath.text + (thirdChar == 0 ? 2 : 3);
while (*r == separator) // ignore duplicate slashes
++r;
}
else
{
r = lastPos;
break;
}
}
else if (secondChar == separator)
else if (secondChar == separator || secondChar == 0) // remove "./"
{
relativePath = relativePath.text + 2;
while (*r == separator) // ignore duplicate slashes
++r;
}
else
{
r = lastPos;
break;
}
}
return File (addTrailingSeparator (path) + relativePath);
path = addTrailingSeparator (path);
path.appendCharPointer (r);
return File (path);
}
File File::getSiblingFile (StringRef fileName) const
@@ -1020,6 +1049,17 @@ public:
expect (tempFile.getSiblingFile ("foo").isAChildOf (temp));
expect (tempFile.hasWriteAccess());
expect (home.getChildFile (".") == home);
expect (home.getChildFile ("..") == home.getParentDirectory());
expect (home.getChildFile (".xyz").getFileName() == ".xyz");
expect (home.getChildFile ("..xyz").getFileName() == "..xyz");
expect (home.getChildFile ("...xyz").getFileName() == "...xyz");
expect (home.getChildFile ("./xyz") == home.getChildFile ("xyz"));
expect (home.getChildFile ("././xyz") == home.getChildFile ("xyz"));
expect (home.getChildFile ("../xyz") == home.getParentDirectory().getChildFile ("xyz"));
expect (home.getChildFile (".././xyz") == home.getParentDirectory().getChildFile ("xyz"));
expect (home.getChildFile ("./../xyz") == home.getParentDirectory().getChildFile ("xyz"));
{
FileOutputStream fo (tempFile);
fo.write ("0123456789", 10);


+ 1
- 1
libs/juce/source/modules/juce_core/files/juce_File.h View File

@@ -48,7 +48,7 @@ public:
//==============================================================================
/** Creates an (invalid) file object.
The file is initially set to an empty path, so getFullPath() will return
The file is initially set to an empty path, so getFullPathName() will return
an empty string, and comparing the file to File::nonexistent will return
true.


+ 2
- 2
libs/juce/source/modules/juce_core/files/juce_WildcardFileFilter.h View File

@@ -66,10 +66,10 @@ public:
//==============================================================================
/** Returns true if the filename matches one of the patterns specified. */
bool isFileSuitable (const File& file) const;
bool isFileSuitable (const File& file) const override;
/** This always returns true. */
bool isDirectorySuitable (const File& file) const;
bool isDirectorySuitable (const File& file) const override;
private:
//==============================================================================


+ 57
- 8
libs/juce/source/modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -44,7 +44,8 @@
#define JUCE_JS_KEYWORDS(X) \
X(var, "var") X(if_, "if") X(else_, "else") X(do_, "do") X(null_, "null") \
X(while_, "while") X(for_, "for") X(break_, "break") X(continue_, "continue") X(undefined, "undefined") \
X(function, "function") X(return_, "return") X(true_, "true") X(false_, "false") X(new_, "new")
X(function, "function") X(return_, "return") X(true_, "true") X(false_, "false") X(new_, "new") \
X(typeof_, "typeof")
namespace TokenTypes
{
@@ -71,6 +72,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
setMethod ("trace", trace);
setMethod ("charToInt", charToInt);
setMethod ("parseInt", IntegerClass::parseInt);
setMethod ("typeof", typeof_internal);
}
Time timeout;
@@ -97,12 +99,13 @@ struct JavascriptEngine::RootObject : public DynamicObject
&& (((a.isUndefined() || a.isVoid()) && (b.isUndefined() || b.isVoid())) || a == b);
}
static String getTokenName (TokenType t) { return t[0] == '$' ? String (t + 1) : ("'" + String (t) + "'"); }
static bool isFunction (const var& v) { return dynamic_cast<FunctionObject*> (v.getObject()) != nullptr; }
static bool isNumericOrUndefined (const var& v) { return v.isInt() || v.isDouble() || v.isInt64() || v.isBool() || v.isUndefined(); }
static int64 getOctalValue (const String& s) { BigInteger b; b.parseString (s, 8); return b.toInt64(); }
static Identifier getPrototypeIdentifier() { static const Identifier i ("prototype"); return i; }
static var* getPropertyPointer (DynamicObject* o, const Identifier& i) { return o->getProperties().getVarPointer (i); }
static String getTokenName (TokenType t) { return t[0] == '$' ? String (t + 1) : ("'" + String (t) + "'"); }
static bool isFunction (const var& v) noexcept { return dynamic_cast<FunctionObject*> (v.getObject()) != nullptr; }
static bool isNumeric (const var& v) noexcept { return v.isInt() || v.isDouble() || v.isInt64() || v.isBool(); }
static bool isNumericOrUndefined (const var& v) noexcept { return isNumeric (v) || v.isUndefined(); }
static int64 getOctalValue (const String& s) { BigInteger b; b.parseString (s, 8); return b.toInt64(); }
static Identifier getPrototypeIdentifier() { static const Identifier i ("prototype"); return i; }
static var* getPropertyPointer (DynamicObject* o, const Identifier& i) noexcept { return o->getProperties().getVarPointer (i); }
//==============================================================================
struct CodeLocation
@@ -1079,7 +1082,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
if (matchIf (TokenTypes::while_)) return parseDoOrWhileLoop (false);
if (matchIf (TokenTypes::do_)) return parseDoOrWhileLoop (true);
if (matchIf (TokenTypes::for_)) return parseForLoop();
if (matchIf (TokenTypes::return_)) return new ReturnStatement (location, matchIf (TokenTypes::semicolon) ? new Expression (location) : parseExpression());
if (matchIf (TokenTypes::return_)) return parseReturn();
if (matchIf (TokenTypes::break_)) return new BreakStatement (location);
if (matchIf (TokenTypes::continue_)) return new ContinueStatement (location);
if (matchIf (TokenTypes::function)) return parseFunction();
@@ -1111,6 +1114,16 @@ struct JavascriptEngine::RootObject : public DynamicObject
return s.release();
}
Statement* parseReturn()
{
if (matchIf (TokenTypes::semicolon))
return new ReturnStatement (location, new Expression (location));
ReturnStatement* r = new ReturnStatement (location, parseExpression());
matchIf (TokenTypes::semicolon);
return r;
}
Statement* parseVar()
{
ScopedPointer<VarStatement> s (new VarStatement (location));
@@ -1345,12 +1358,21 @@ struct JavascriptEngine::RootObject : public DynamicObject
return new PostAssignment (location, e, new OpType (location, lhs2, one));
}
Expression* parseTypeof()
{
ScopedPointer<FunctionCall> f (new FunctionCall (location));
f->object = new UnqualifiedName (location, "typeof");
f->arguments.add (parseExpression());
return f.release();
}
Expression* parseUnary()
{
if (matchIf (TokenTypes::minus)) { ExpPtr a (new LiteralValue (location, (int) 0)), b (parseUnary()); return new SubtractionOp (location, a, b); }
if (matchIf (TokenTypes::logicalNot)) { ExpPtr a (new LiteralValue (location, (int) 0)), b (parseUnary()); return new EqualsOp (location, a, b); }
if (matchIf (TokenTypes::plusplus)) return parsePreIncDec<AdditionOp>();
if (matchIf (TokenTypes::minusminus)) return parsePreIncDec<SubtractionOp>();
if (matchIf (TokenTypes::typeof_)) return parseTypeof();
return parseFactor();
}
@@ -1478,6 +1500,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
setMethod ("contains", contains);
setMethod ("remove", remove);
setMethod ("join", join);
setMethod ("push", push);
}
static Identifier getClassName() { static const Identifier i ("Array"); return i; }
@@ -1508,6 +1531,19 @@ struct JavascriptEngine::RootObject : public DynamicObject
return strings.joinIntoString (getString (a, 0));
}
static var push (Args a)
{
if (Array<var>* array = a.thisObject.getArray())
{
for (int i = 0; i < a.numArguments; ++i)
array->add (a.arguments[i]);
return array->size();
}
return var::undefined();
}
};
//==============================================================================
@@ -1638,6 +1674,19 @@ struct JavascriptEngine::RootObject : public DynamicObject
static var trace (Args a) { Logger::outputDebugString (JSON::toString (a.thisObject)); return var::undefined(); }
static var charToInt (Args a) { return (int) (getString (a, 0)[0]); }
static var typeof_internal (Args a)
{
var v (get (a, 0));
if (v.isVoid()) return "void";
if (v.isString()) return "string";
if (isNumeric (v)) return "number";
if (isFunction (v) || v.isMethod()) return "function";
if (v.isObject()) return "object";
return "undefined";
}
static var exec (Args a)
{
if (RootObject* root = dynamic_cast<RootObject*> (a.thisObject.getObject()))


+ 7
- 6
libs/juce/source/modules/juce_core/juce_core.cpp View File

@@ -35,7 +35,10 @@
#error "Incorrect use of JUCE cpp file"
#endif
#include "native/juce_BasicNativeHeaders.h"
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
#define JUCE_CORE_INCLUDE_COM_SMART_PTR 1
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#include "juce_core.h"
#include <locale>
@@ -80,6 +83,7 @@
#if JUCE_LINUX
#include <langinfo.h>
#include <ifaddrs.h>
#include <sys/resource.h>
#if JUCE_USE_CURL
#include <curl/curl.h>
@@ -140,6 +144,7 @@ namespace juce
#include "maths/juce_Expression.cpp"
#include "maths/juce_Random.cpp"
#include "memory/juce_MemoryBlock.cpp"
#include "misc/juce_RuntimePermissions.cpp"
#include "misc/juce_Result.cpp"
#include "misc/juce_Uuid.cpp"
#include "network/juce_MACAddress.cpp"
@@ -180,10 +185,6 @@ namespace juce
#include "files/juce_WildcardFileFilter.cpp"
//==============================================================================
#if JUCE_MAC || JUCE_IOS
#include "native/juce_osx_ObjCHelpers.h"
#endif
#if JUCE_ANDROID
#include "native/juce_android_JNIHelpers.h"
#endif
@@ -203,7 +204,6 @@ namespace juce
//==============================================================================
#elif JUCE_WINDOWS
#include "native/juce_win32_ComSmartPtr.h"
#include "native/juce_win32_Files.cpp"
#include "native/juce_win32_Network.cpp"
#include "native/juce_win32_Registry.cpp"
@@ -229,6 +229,7 @@ namespace juce
#include "native/juce_android_Network.cpp"
#include "native/juce_android_SystemStats.cpp"
#include "native/juce_android_Threads.cpp"
#include "native/juce_android_RuntimePermissions.cpp"
#endif


+ 25
- 6
libs/juce/source/modules/juce_core/juce_core.h View File

@@ -41,7 +41,7 @@
#include "system/juce_TargetPlatform.h"
//=============================================================================
//==============================================================================
/** Config: JUCE_FORCE_DEBUG
Normally, JUCE_DEBUG is set to 1 or 0 based on compiler and project settings,
@@ -51,7 +51,7 @@
//#define JUCE_FORCE_DEBUG 0
#endif
//=============================================================================
//==============================================================================
/** Config: JUCE_LOG_ASSERTIONS
If this flag is enabled, the jassert and jassertfalse macros will always use Logger::writeToLog()
@@ -71,7 +71,7 @@
#endif
#endif
//=============================================================================
//==============================================================================
/** Config: JUCE_CHECK_MEMORY_LEAKS
Enables a memory-leak check for certain objects when the app terminates. See the LeakedObjectDetector
@@ -81,7 +81,7 @@
#define JUCE_CHECK_MEMORY_LEAKS 1
#endif
//=============================================================================
//==============================================================================
/** Config: JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
In a Visual C++ build, this can be used to stop the required system libs being
@@ -130,8 +130,12 @@
#define JUCE_STRING_UTF_TYPE 8
#endif
//=============================================================================
//=============================================================================
//==============================================================================
//==============================================================================
#if JUCE_CORE_INCLUDE_NATIVE_HEADERS
#include "native/juce_BasicNativeHeaders.h"
#endif
#include "system/juce_StandardHeader.h"
@@ -188,6 +192,7 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe
#include "threads/juce_CriticalSection.h"
#include "maths/juce_Range.h"
#include "maths/juce_NormalisableRange.h"
#include "maths/juce_StatisticsAccumulator.h"
#include "containers/juce_ElementComparator.h"
#include "containers/juce_ArrayAllocationBase.h"
#include "containers/juce_Array.h"
@@ -237,6 +242,7 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe
#include "maths/juce_BigInteger.h"
#include "maths/juce_Expression.h"
#include "maths/juce_Random.h"
#include "misc/juce_RuntimePermissions.h"
#include "misc/juce_Uuid.h"
#include "misc/juce_WindowsRegistry.h"
#include "system/juce_SystemStats.h"
@@ -269,6 +275,19 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe
#include "containers/juce_PropertySet.h"
#include "memory/juce_SharedResourcePointer.h"
#if JUCE_CORE_INCLUDE_OBJC_HELPERS && (JUCE_MAC || JUCE_IOS)
#include "native/juce_osx_ObjCHelpers.h"
#endif
#if JUCE_CORE_INCLUDE_COM_SMART_PTR && JUCE_WINDOWS
#include "native/juce_win32_ComSmartPtr.h"
#endif
#if JUCE_CORE_INCLUDE_JNI_HELPERS && JUCE_ANDROID
#include "native/juce_android_JNIHelpers.h"
#endif
#ifndef DOXYGEN
/*
As the very long class names here try to explain, the purpose of this code is to cause


+ 1
- 1
libs/juce/source/modules/juce_core/maths/juce_BigInteger.cpp View File

@@ -315,7 +315,7 @@ inline static int highestBitInInt (uint32 n) noexcept
{
jassert (n != 0); // (the built-in functions may not work for n = 0)
#if JUCE_GCC
#if JUCE_GCC || JUCE_CLANG
return 31 - __builtin_clz (n);
#elif JUCE_USE_MSVC_INTRINSICS
unsigned long highest;


+ 10
- 6
libs/juce/source/modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -324,9 +324,9 @@ template <>
inline float juce_hypot (float a, float b) noexcept
{
#if JUCE_MSVC
return (_hypotf (a, b));
return _hypotf (a, b);
#else
return (hypotf (a, b));
return hypotf (a, b);
#endif
}
#endif
@@ -356,12 +356,16 @@ const float float_Pi = 3.14159265358979323846f;
/** Converts an angle in degrees to radians. */
template <typename FloatType>
FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * static_cast<FloatType> (double_Pi / 180.0); }
inline float degreesToRadians (float degrees) noexcept { return degrees * (float_Pi / 180.0f); }
/** Converts an angle in degrees to radians. */
inline double degreesToRadians (double degrees) noexcept { return degrees * (double_Pi / 180.0); }
/** Converts an angle in radians to degrees. */
template <typename FloatType>
FloatType radiansToDegrees (FloatType radians) noexcept { return radians * static_cast<FloatType> (180.0 / double_Pi); }
inline float radiansToDegrees (float radians) noexcept { return radians * (180.0f / float_Pi); }
/** Converts an angle in radians to degrees. */
inline double radiansToDegrees (double radians) noexcept { return radians * (180.0 / double_Pi); }
//==============================================================================


+ 145
- 0
libs/juce/source/modules/juce_core/maths/juce_StatisticsAccumulator.h View File

@@ -0,0 +1,145 @@
/*
==============================================================================
This file is part of the juce_core module of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
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.
THE 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.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
All other JUCE modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.juce.com
==============================================================================
*/
#ifndef JUCE_STATISTICSACCUMULATOR_H_INCLUDED
#define JUCE_STATISTICSACCUMULATOR_H_INCLUDED
//==============================================================================
/**
A class that measures various statistics about a series of floating point
values that it is given.
*/
template <typename FloatType>
class StatisticsAccumulator
{
public:
//==============================================================================
/** Constructs a new StatisticsAccumulator. */
StatisticsAccumulator() noexcept
: count (0),
minimum ( std::numeric_limits<FloatType>::infinity()),
maximum (-std::numeric_limits<FloatType>::infinity())
{}
//==============================================================================
/** Add a new value to the accumulator.
This will update all running statistics accordingly.
*/
void addValue (FloatType v) noexcept
{
jassert (juce_isfinite (v));
sum += v;
sumSquares += v * v;
++count;
if (v > maximum) maximum = v;
if (v < minimum) minimum = v;
}
/** Reset the accumulator.
This will reset all currently saved statistcs.
*/
void reset() noexcept { *this = StatisticsAccumulator<FloatType>(); }
//==============================================================================
/** Returns the average (arithmetic mean) of all previously added values.
If no values have been added yet, this will return zero.
*/
FloatType getAverage() const noexcept
{
return count > 0 ? sum / (FloatType) count
: FloatType();
}
/** Returns the variance of all previously added values.
If no values have been added yet, this will return zero.
*/
FloatType getVariance() const noexcept
{
return count > 0 ? (sumSquares - sum * sum / (FloatType) count) / (FloatType) count
: FloatType();
}
/** Returns the standard deviation of all previously added values.
If no values have been added yet, this will return zero.
*/
FloatType getStandardDeviation() const noexcept
{
return std::sqrt (getVariance());
}
/** Returns the smallest of all previously added values.
If no values have been added yet, this will return positive infinity.
*/
FloatType getMinValue() const noexcept
{
return minimum;
}
/** Returns the largest of all previously added values.
If no values have been added yet, this will return negative infinity.
*/
FloatType getMaxValue() const noexcept
{
return maximum;
}
/** Returns how many values have been added to this accumulator. */
size_t getCount() const noexcept
{
return count;
}
private:
//==============================================================================
struct KahanSum
{
KahanSum() noexcept : sum(), error() {}
operator FloatType() const noexcept { return sum; }
void JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS operator+= (FloatType value) noexcept
{
FloatType correctedValue = value - error;
FloatType newSum = sum + correctedValue;
error = (newSum - sum) - correctedValue;
sum = newSum;
}
FloatType sum, error;
};
//==============================================================================
size_t count;
KahanSum sum, sumSquares;
FloatType minimum, maximum;
};
#endif // JUCE_STATISTICSACCUMULATOR_H_INCLUDED

+ 1
- 1
libs/juce/source/modules/juce_core/memory/juce_Atomic.h View File

@@ -201,7 +201,7 @@ private:
#endif
//==============================================================================
#elif (JUCE_GCC || JUCE_CLANG) && ! JUCE_MSVC
#elif JUCE_GCC || JUCE_CLANG
#define JUCE_ATOMICS_GCC 1 // GCC with intrinsics
#if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes)


+ 1
- 1
libs/juce/source/modules/juce_core/memory/juce_ByteOrder.h View File

@@ -157,7 +157,7 @@ inline uint32 ByteOrder::swap (uint32 n) noexcept
{
#if JUCE_MAC || JUCE_IOS
return OSSwapInt32 (n);
#elif JUCE_GCC && JUCE_INTEL && ! JUCE_NO_INLINE_ASM
#elif (JUCE_GCC || JUCE_CLANG) && JUCE_INTEL && ! JUCE_NO_INLINE_ASM
asm("bswap %%eax" : "=a"(n) : "a"(n));
return n;
#elif JUCE_USE_MSVC_INTRINSICS


+ 6
- 0
libs/juce/source/modules/juce_core/memory/juce_OptionalScopedPointer.h View File

@@ -180,6 +180,12 @@ private:
//==============================================================================
ScopedPointer<ObjectType> object;
bool shouldDelete;
// This is here to avoid people accidentally taking a second owned copy of
// a scoped pointer, which is almost certainly not what you intended to do!
// If you hit a problem with this, you probably meant to say
// myPointer.setOwned (myScopedPointer.release())
void setOwned (const ScopedPointer<ObjectType>&) JUCE_DELETED_FUNCTION;
};


+ 48
- 0
libs/juce/source/modules/juce_core/misc/juce_RuntimePermissions.cpp View File

@@ -0,0 +1,48 @@
/*
==============================================================================
This file is part of the juce_core module of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
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.
THE 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.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
All other JUCE modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.juce.com
==============================================================================
*/
#if ! JUCE_ANDROID // We currently don't request runtime permissions on any other platform
// than Android, so this file contains a dummy implementation for those.
// This may change in the future.
void RuntimePermissions::request (PermissionID /*permission*/, Callback callback)
{
callback (true);
}
bool RuntimePermissions::isRequired (PermissionID /*permission*/)
{
return false;
}
bool RuntimePermissions::isGranted (PermissionID /*permission*/)
{
return true;
}
#endif

+ 131
- 0
libs/juce/source/modules/juce_core/misc/juce_RuntimePermissions.h View File

@@ -0,0 +1,131 @@
/*
==============================================================================
This file is part of the juce_core module of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
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.
THE 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.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
All other JUCE modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.juce.com
==============================================================================
*/
#ifndef JUCE_RUNTIMEPERMISSIONS_H_INCLUDED
#define JUCE_RUNTIMEPERMISSIONS_H_INCLUDED
//==============================================================================
/**
Class to handle app runtime permissions for certain functionality on some platforms.
The use of this class is currently only required if the app should run on
Android API level 23 and higher.
On lower API levels, the permissions are specified in the app manifest. On iOS,
runtime permission requests are handled automatically by the Apple APIs and not
manually in the app code. On Windows, OS X, and Linux, runtime permissions are not
used at all. In all these cases, request() will simply call through to the
callback with no overhead and pass true (making it safe to use on all platforms).
For example, to enable audio recording on Android in your cross-platform app,
you could modify your code as follows:
Old code:
audioDeviceManager.initialise (2, 2, nullptr, true, String(), nullptr);
New code:
RuntimePermissions::request (
RuntimePermissions::audioRecording,
[this] (bool wasGranted)
{
if (! wasGranted)
{
// e.g. display an error or initialise with 0 input channels
return;
}
audioDeviceManager.initialise (2, 2, nullptr, true, String(), nullptr);
}
);
*/
class JUCE_API RuntimePermissions
{
public:
//==========================================================================
enum PermissionID
{
/** Permission to access the microphone (required on Android).
You need to request this, for example, to initialise an AudioDeviceManager with
a non-zero number of input channels, and to open the default audio input device.
*/
recordAudio = 1,
/** Permission to scan for and pair to Bluetooth MIDI devices (required on Android).
You need to request this before calling BluetoothMidiDevicePairingDialogue::open(),
otherwise no devices will be found.
*/
bluetoothMidi = 2,
};
//==========================================================================
/** Function type of runtime permission request callbacks. */
#if JUCE_COMPILER_SUPPORTS_LAMBDAS
typedef std::function<void (bool)> Callback;
#else
typedef void (*Callback) (bool);
#endif
//==========================================================================
/** Call this method to request a runtime permission.
@param permission The PermissionID of the permission you want to request.
@param callback The callback to be called after the request has been granted
or denied; the argument passed will be true if the permission
has been granted and false otherwise.
If no runtime request is required or possible to obtain the permission, the
callback will be called immediately. The argument passed in will be true
if the permission is granted or no permission is required on this platform,
and false otherwise.
If a runtime request is required to obtain the permission, the callback
will be called asynchronously after the OS has granted or denied the requested
permission (typically by displaying a dialog box to the user and waiting until
the user has responded).
*/
static void request (PermissionID permission, Callback callback);
/** Returns whether a runtime request is required to obtain the permission
on the current platform.
*/
static bool isRequired (PermissionID permission);
/** Returns true if the app has been already granted this permission, either
via a previous runtime request or otherwise, or no permission is necessary.
Note that this can be false even if isRequired returns false. In this case,
the permission can not be obtained at all at runtime.
*/
static bool isGranted (PermissionID permission);
};
#endif // JUCE_RUNTIMEPERMISSIONS_H_INCLUDED

+ 14
- 0
libs/juce/source/modules/juce_core/native/java/AndroidRuntimePermissions.java View File

@@ -0,0 +1,14 @@
private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback);
@Override
public void onRequestPermissionsResult (int permissionID, String permissions[], int[] grantResults)
{
boolean permissionsGranted = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);
if (! permissionsGranted)
Log.d ("JUCE", "onRequestPermissionsResult: runtime permission was DENIED: " + getAndroidPermissionName (permissionID));
Long ptrToCallback = permissionCallbackPtrMap.get (permissionID);
permissionCallbackPtrMap.remove (permissionID);
androidRuntimePermissionsCallback (permissionsGranted, ptrToCallback);
}

+ 145
- 23
libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java View File

@@ -30,14 +30,14 @@ import android.content.DialogInterface;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.os.Handler;
import android.os.Build;
import android.os.Process;
import android.os.ParcelUuid;
import android.os.Environment;
import android.view.*;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
@@ -49,19 +49,16 @@ import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import java.lang.Runnable;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.TimerTask;
import java.util.*;
import java.io.*;
import java.net.URL;
import java.net.HttpURLConnection;
import android.media.AudioManager;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.support.v4.content.ContextCompat;
import android.support.v4.app.ActivityCompat;
import android.Manifest;
$$JuceAndroidMidiImports$$ // If you get an error here, you need to re-save your project with the introjucer!
@@ -74,6 +71,73 @@ public class JuceAppActivity extends Activity
System.loadLibrary ("juce_jni");
}
//==============================================================================
public boolean isPermissionDeclaredInManifest (int permissionID)
{
String permissionToCheck = getAndroidPermissionName(permissionID);
try
{
PackageInfo info = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS);
if (info.requestedPermissions != null)
for (String permission : info.requestedPermissions)
if (permission.equals (permissionToCheck))
return true;
}
catch (PackageManager.NameNotFoundException e)
{
Log.d ("JUCE", "isPermissionDeclaredInManifest: PackageManager.NameNotFoundException = " + e.toString());
}
Log.d ("JUCE", "isPermissionDeclaredInManifest: could not find requested permission " + permissionToCheck);
return false;
}
//==============================================================================
// these have to match the values of enum PermissionID in C++ class RuntimePermissions:
private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1;
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
private static String getAndroidPermissionName (int permissionID)
{
switch (permissionID)
{
case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO;
case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION;
}
// unknown permission ID!
assert false;
return new String();
}
public boolean isPermissionGranted (int permissionID)
{
return ContextCompat.checkSelfPermission (this, getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED;
}
private Map<Integer, Long> permissionCallbackPtrMap;
public void requestRuntimePermission (int permissionID, long ptrToCallback)
{
String permissionName = getAndroidPermissionName (permissionID);
if (ContextCompat.checkSelfPermission (this, permissionName) != PackageManager.PERMISSION_GRANTED)
{
// remember callbackPtr, request permissions, and let onRequestPermissionResult call callback asynchronously
permissionCallbackPtrMap.put (permissionID, ptrToCallback);
ActivityCompat.requestPermissions (this, new String[]{permissionName}, permissionID);
}
else
{
// permissions were already granted before, we can call callback directly
androidRuntimePermissionsCallback (true, ptrToCallback);
}
}
$$JuceAndroidRuntimePermissionsCode$$ // If you get an error here, you need to re-save your project with the introjucer!
//==============================================================================
public static class MidiPortID extends Object
{
@@ -132,10 +196,13 @@ public class JuceAppActivity extends Activity
super.onCreate (savedInstanceState);
isScreenSaverEnabled = true;
hideActionBar();
viewHolder = new ViewHolder (this);
setContentView (viewHolder);
setVolumeControlStream (AudioManager.STREAM_MUSIC);
permissionCallbackPtrMap = new HashMap<Integer, Long>();
}
@Override
@@ -174,6 +241,49 @@ public class JuceAppActivity extends Activity
getApplicationInfo().dataDir);
}
private void hideActionBar()
{
// get "getActionBar" method
java.lang.reflect.Method getActionBarMethod = null;
try
{
getActionBarMethod = this.getClass().getMethod ("getActionBar");
}
catch (SecurityException e) { return; }
catch (NoSuchMethodException e) { return; }
if (getActionBarMethod == null) return;
// invoke "getActionBar" method
Object actionBar = null;
try
{
actionBar = getActionBarMethod.invoke (this);
}
catch (java.lang.IllegalArgumentException e) { return; }
catch (java.lang.IllegalAccessException e) { return; }
catch (java.lang.reflect.InvocationTargetException e) { return; }
if (actionBar == null) return;
// get "hide" method
java.lang.reflect.Method actionBarHideMethod = null;
try
{
actionBarHideMethod = actionBar.getClass().getMethod ("hide");
}
catch (SecurityException e) { return; }
catch (NoSuchMethodException e) { return; }
if (actionBarHideMethod == null) return;
// invoke "hide" method
try
{
actionBarHideMethod.invoke (actionBar);
}
catch (java.lang.IllegalArgumentException e) {}
catch (java.lang.IllegalAccessException e) {}
catch (java.lang.reflect.InvocationTargetException e) {}
}
//==============================================================================
private native void launchApp (String appFile, String appDataDir);
private native void quitApp();
@@ -691,7 +801,7 @@ public class JuceAppActivity extends Activity
int format, int width, int height);
}
public NativeSurfaceView createNativeSurfaceView(long nativeSurfacePtr)
public NativeSurfaceView createNativeSurfaceView (long nativeSurfacePtr)
{
return new NativeSurfaceView (this, nativeSurfacePtr);
}
@@ -917,6 +1027,17 @@ public class JuceAppActivity extends Activity
: locale.getDisplayLanguage (java.util.Locale.US);
}
private static final String getFileLocation (String type)
{
return Environment.getExternalStoragePublicDirectory (type).getAbsolutePath();
}
public static final String getDocumentsFolder() { return Environment.getDataDirectory().getAbsolutePath(); }
public static final String getPicturesFolder() { return getFileLocation (Environment.DIRECTORY_PICTURES); }
public static final String getMusicFolder() { return getFileLocation (Environment.DIRECTORY_MUSIC); }
public static final String getMoviesFolder() { return getFileLocation (Environment.DIRECTORY_MOVIES); }
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
//==============================================================================
private final class SingleMediaScanner implements MediaScannerConnectionClient
{
@@ -1041,23 +1162,24 @@ public class JuceAppActivity extends Activity
return null;
java.lang.reflect.Method method;
try {
try
{
method = obj.getClass().getMethod ("getProperty", String.class);
} catch (SecurityException e) {
return null;
} catch (NoSuchMethodException e) {
return null;
}
catch (SecurityException e) { return null; }
catch (NoSuchMethodException e) { return null; }
if (method == null)
return null;
try {
try
{
return (String) method.invoke (obj, property);
} catch (java.lang.IllegalArgumentException e) {
} catch (java.lang.IllegalAccessException e) {
} catch (java.lang.reflect.InvocationTargetException e) {
}
catch (java.lang.IllegalArgumentException e) {}
catch (java.lang.IllegalAccessException e) {}
catch (java.lang.reflect.InvocationTargetException e) {}
return null;
}
@@ -1075,8 +1197,9 @@ public class JuceAppActivity extends Activity
private static class JuceThread extends Thread
{
public JuceThread (long host)
public JuceThread (long host, String threadName, long threadStackSize)
{
super (null, null, threadName, threadStackSize);
_this = host;
}
@@ -1089,9 +1212,8 @@ public class JuceAppActivity extends Activity
private long _this;
}
public final Thread createNewThread(long host)
public final Thread createNewThread(long host, String threadName, long threadStackSize)
{
return new JuceThread(host);
return new JuceThread(host, threadName, threadStackSize);
}
}

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

Loading…
Cancel
Save