Browse Source

Update juce

tags/2018-04-16
falkTX 6 years ago
parent
commit
af87c602a1
100 changed files with 4669 additions and 931 deletions
  1. +1
    -1
      libs/juce/source/doxygen/Doxyfile
  2. +1
    -1
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
  3. +22
    -23
      libs/juce/source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h
  4. +34
    -121
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  5. +16
    -9
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  6. +5
    -0
      libs/juce/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp
  7. +7
    -1
      libs/juce/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp
  8. +41
    -13
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp
  9. +6
    -15
      libs/juce/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp
  10. +7
    -0
      libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
  11. +23
    -7
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  12. +301
    -141
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm
  13. +1
    -11
      libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  14. +3
    -1
      libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
  15. +38
    -0
      libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
  16. +11
    -7
      libs/juce/source/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm
  17. +20
    -7
      libs/juce/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  18. +3
    -0
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h
  19. +64
    -0
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  20. +2
    -2
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VSTCommon.h
  21. +3
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
  22. +26
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h
  23. +4
    -1
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp
  24. +22
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h
  25. +22
    -2
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  26. +3
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  27. +1
    -1
      libs/juce/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h
  28. +2
    -2
      libs/juce/source/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp
  29. +1
    -1
      libs/juce/source/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h
  30. +6
    -6
      libs/juce/source/modules/juce_audio_utils/players/juce_SoundPlayer.cpp
  31. +5
    -1
      libs/juce/source/modules/juce_audio_utils/players/juce_SoundPlayer.h
  32. +2
    -2
      libs/juce/source/modules/juce_core/containers/juce_DynamicObject.cpp
  33. +2
    -2
      libs/juce/source/modules/juce_core/containers/juce_DynamicObject.h
  34. +9
    -5
      libs/juce/source/modules/juce_core/containers/juce_HashMap.h
  35. +31
    -42
      libs/juce/source/modules/juce_core/containers/juce_SortedSet.h
  36. +15
    -9
      libs/juce/source/modules/juce_core/javascript/juce_JSON.cpp
  37. +6
    -2
      libs/juce/source/modules/juce_core/javascript/juce_JSON.h
  38. +1
    -1
      libs/juce/source/modules/juce_core/javascript/juce_Javascript.cpp
  39. +7
    -0
      libs/juce/source/modules/juce_core/memory/juce_HeapBlock.h
  40. +971
    -0
      libs/juce/source/modules/juce_core/native/java/IInAppBillingService.java
  41. +38
    -47
      libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java
  42. +86
    -0
      libs/juce/source/modules/juce_core/native/juce_android_Files.cpp
  43. +125
    -28
      libs/juce/source/modules/juce_core/native/juce_android_JNIHelpers.h
  44. +93
    -0
      libs/juce/source/modules/juce_core/native/juce_android_SystemStats.cpp
  45. +5
    -0
      libs/juce/source/modules/juce_core/native/juce_mac_ClangBugWorkaround.h
  46. +5
    -0
      libs/juce/source/modules/juce_core/native/juce_mac_Files.mm
  47. +2
    -0
      libs/juce/source/modules/juce_core/native/juce_mac_Network.mm
  48. +10
    -0
      libs/juce/source/modules/juce_core/native/juce_osx_ObjCHelpers.h
  49. +8
    -14
      libs/juce/source/modules/juce_core/native/juce_posix_SharedCode.h
  50. +13
    -1
      libs/juce/source/modules/juce_core/native/juce_win32_SystemStats.cpp
  51. +18
    -0
      libs/juce/source/modules/juce_core/system/juce_CompilerSupport.h
  52. +5
    -5
      libs/juce/source/modules/juce_core/text/juce_String.cpp
  53. +16
    -8
      libs/juce/source/modules/juce_core/text/juce_String.h
  54. +31
    -2
      libs/juce/source/modules/juce_core/threads/juce_Thread.cpp
  55. +15
    -9
      libs/juce/source/modules/juce_core/threads/juce_Thread.h
  56. +79
    -44
      libs/juce/source/modules/juce_core/threads/juce_ThreadPool.cpp
  57. +24
    -11
      libs/juce/source/modules/juce_core/threads/juce_ThreadPool.h
  58. +3
    -1
      libs/juce/source/modules/juce_core/time/juce_PerformanceCounter.h
  59. +9
    -6
      libs/juce/source/modules/juce_events/broadcasters/juce_AsyncUpdater.h
  60. +80
    -16
      libs/juce/source/modules/juce_events/native/juce_android_Messaging.cpp
  61. +19
    -29
      libs/juce/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp
  62. +6
    -12
      libs/juce/source/modules/juce_graphics/contexts/juce_GraphicsContext.h
  63. +19
    -20
      libs/juce/source/modules/juce_graphics/geometry/juce_Path.cpp
  64. +18
    -18
      libs/juce/source/modules/juce_graphics/geometry/juce_Path.h
  65. +30
    -30
      libs/juce/source/modules/juce_graphics/geometry/juce_Point.h
  66. +6
    -3
      libs/juce/source/modules/juce_graphics/images/juce_Image.cpp
  67. +9
    -10
      libs/juce/source/modules/juce_graphics/native/juce_RenderingHelpers.h
  68. +5
    -12
      libs/juce/source/modules/juce_gui_basics/buttons/juce_Button.cpp
  69. +1
    -1
      libs/juce/source/modules/juce_gui_basics/buttons/juce_Button.h
  70. +6
    -9
      libs/juce/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp
  71. +5
    -2
      libs/juce/source/modules/juce_gui_basics/buttons/juce_DrawableButton.h
  72. +50
    -54
      libs/juce/source/modules/juce_gui_basics/components/juce_Component.cpp
  73. +2
    -2
      libs/juce/source/modules/juce_gui_basics/components/juce_Component.h
  74. +5
    -5
      libs/juce/source/modules/juce_gui_basics/components/juce_Desktop.h
  75. +1
    -34
      libs/juce/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp
  76. +3
    -3
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h
  77. +1
    -1
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h
  78. +1
    -1
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h
  79. +2
    -2
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h
  80. +8
    -0
      libs/juce/source/modules/juce_gui_basics/juce_gui_basics.cpp
  81. +9
    -0
      libs/juce/source/modules/juce_gui_basics/juce_gui_basics.h
  82. +1025
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_Grid.cpp
  83. +174
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_Grid.h
  84. +182
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_GridItem.cpp
  85. +223
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_GridItem.h
  86. +257
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_GridUnitTests.cpp
  87. +1
    -1
      libs/juce/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp
  88. +1
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h
  89. +35
    -18
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  90. +6
    -3
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h
  91. +6
    -3
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp
  92. +2
    -4
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp
  93. +11
    -8
      libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  94. +6
    -0
      libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.h
  95. +10
    -5
      libs/juce/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp
  96. +3
    -0
      libs/juce/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.h
  97. +68
    -9
      libs/juce/source/modules/juce_gui_basics/native/juce_android_Windowing.cpp
  98. +2
    -2
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm
  99. +40
    -0
      libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  100. +1
    -1
      libs/juce/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h

+ 1
- 1
libs/juce/source/doxygen/Doxyfile View File

@@ -397,7 +397,7 @@ SUBGROUPING = YES
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.

INLINE_GROUPED_CLASSES = YES
INLINE_GROUPED_CLASSES = NO

# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in


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

@@ -25,7 +25,7 @@
#if JUCE_INTEL
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0;
#else
#define JUCE_SNAP_TO_ZERO(n)
#define JUCE_SNAP_TO_ZERO(n) ignoreUnused (n)
#endif
//==============================================================================


+ 22
- 23
libs/juce/source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h View File

@@ -36,6 +36,15 @@ struct CoreAudioLayouts
return AudioChannelSet::channelSetWithChannels (getCoreAudioLayoutChannels (layout));
}
/** Convert CoreAudio's native AudioChannelLayoutTag to JUCE's AudioChannelSet.
Note that this method cannot preserve the order of channels.
*/
static AudioChannelSet fromCoreAudio (AudioChannelLayoutTag layoutTag)
{
return AudioChannelSet::channelSetWithChannels (getSpeakerLayoutForCoreAudioTag (layoutTag));
}
/** Convert JUCE's AudioChannelSet to CoreAudio's AudioChannelLayoutTag.
Note that this method cannot preserve the order of channels.
@@ -67,7 +76,7 @@ struct CoreAudioLayouts
/** Convert CoreAudio's native AudioChannelLayout to an array of JUCE ChannelTypes. */
static Array<AudioChannelSet::ChannelType> getCoreAudioLayoutChannels (const AudioChannelLayout& layout)
{
switch (layout.mChannelLayoutTag)
switch (layout.mChannelLayoutTag & 0xffff0000)
{
case kAudioChannelLayoutTag_UseChannelBitmap:
return AudioChannelSet::fromWaveChannelMask (static_cast<int> (layout.mChannelBitmap)).getChannelTypes();
@@ -94,30 +103,12 @@ struct CoreAudioLayouts
return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag);
}
//==============================================================================
/* Convert between a CoreAudio and JUCE channel indices - and vice versa. */
// TODO: Fabian remove this
// static int convertChannelIndex (const AudioChannelLayout& caLayout, const AudioChannelSet& juceLayout, int index, bool fromJUCE)
// {
// auto coreAudioChannels = getCoreAudioLayoutChannels (caLayout);
//
// jassert (juceLayout.size() == coreAudioChannels.size());
// jassert (index >= 0 && index < juceLayout.size());
//
// return (fromJUCE ? coreAudioChannels.indexOf (juceLayout.getTypeOfChannel (index))
// : juceLayout.getChannelIndexForType (coreAudioChannels.getReference (index)));
// }
private:
//==============================================================================
struct LayoutTagSpeakerList
{
AudioChannelLayoutTag tag;
AudioChannelSet::ChannelType channelTypes[16];
};
static Array<AudioChannelSet::ChannelType> getSpeakerLayoutForCoreAudioTag (AudioChannelLayoutTag tag)
{
// You need to specify the full AudioChannelLayout when using
// the UseChannelBitmap and UseChannelDescriptions layout tag
jassert (tag != kAudioChannelLayoutTag_UseChannelBitmap && tag != kAudioChannelLayoutTag_UseChannelDescriptions);
Array<AudioChannelSet::ChannelType> speakers;
for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
@@ -139,6 +130,14 @@ private:
return speakers;
}
private:
//==============================================================================
struct LayoutTagSpeakerList
{
AudioChannelLayoutTag tag;
AudioChannelSet::ChannelType channelTypes[16];
};
static Array<AudioChannelLayoutTag> createKnownCoreAudioTags()
{
Array<AudioChannelLayoutTag> tags;


+ 34
- 121
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -24,20 +24,8 @@ SynthesiserSound::SynthesiserSound() {}
SynthesiserSound::~SynthesiserSound() {}
//==============================================================================
SynthesiserVoice::SynthesiserVoice()
: currentSampleRate (44100.0),
currentlyPlayingNote (-1),
currentPlayingMidiChannel (0),
noteOnTime (0),
keyIsDown (false),
sustainPedalDown (false),
sostenutoPedalDown (false)
{
}
SynthesiserVoice::~SynthesiserVoice()
{
}
SynthesiserVoice::SynthesiserVoice() {}
SynthesiserVoice::~SynthesiserVoice() {}
bool SynthesiserVoice::isPlayingChannel (const int midiChannel) const
{
@@ -83,11 +71,6 @@ void SynthesiserVoice::renderNextBlock (AudioBuffer<double>& outputBuffer,
//==============================================================================
Synthesiser::Synthesiser()
: sampleRate (0),
lastNoteOnCounter (0),
minimumSubBlockSize (32),
subBlockSubdivisionIsStrict (false),
shouldStealNotes (true)
{
for (int i = 0; i < numElementsInArray (lastPitchWheelValues); ++i)
lastPitchWheelValues[i] = 0x2000;
@@ -159,13 +142,11 @@ void Synthesiser::setCurrentPlaybackSampleRate (const double newRate)
if (sampleRate != newRate)
{
const ScopedLock sl (lock);
allNotesOff (0, false);
sampleRate = newRate;
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->setCurrentPlaybackSampleRate (newRate);
for (auto* voice : voices)
voice->setCurrentPlaybackSampleRate (newRate);
}
}
@@ -230,25 +211,19 @@ void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio,
}
// explicit template instantiation
template void Synthesiser::processNextBlock<float> (AudioBuffer<float>& outputAudio,
const MidiBuffer& midiData,
int startSample,
int numSamples);
template void Synthesiser::processNextBlock<double> (AudioBuffer<double>& outputAudio,
const MidiBuffer& midiData,
int startSample,
int numSamples);
template void Synthesiser::processNextBlock<float> (AudioBuffer<float>&, const MidiBuffer&, int, int);
template void Synthesiser::processNextBlock<double> (AudioBuffer<double>&, const MidiBuffer&, int, int);
void Synthesiser::renderVoices (AudioBuffer<float>& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
for (auto* voice : voices)
voice->renderNextBlock (buffer, startSample, numSamples);
}
void Synthesiser::renderVoices (AudioBuffer<double>& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
for (auto* voice : voices)
voice->renderNextBlock (buffer, startSample, numSamples);
}
void Synthesiser::handleMidiEvent (const MidiMessage& m)
@@ -298,23 +273,15 @@ void Synthesiser::noteOn (const int midiChannel,
{
const ScopedLock sl (lock);
for (int i = sounds.size(); --i >= 0;)
for (auto* sound : sounds)
{
SynthesiserSound* const sound = sounds.getUnchecked(i);
if (sound->appliesToNote (midiNoteNumber)
&& sound->appliesToChannel (midiChannel))
if (sound->appliesToNote (midiNoteNumber) && sound->appliesToChannel (midiChannel))
{
// If hitting a note that's still ringing, stop it first (it could be
// still playing because of the sustain or sostenuto pedal).
for (int j = voices.size(); --j >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (j);
if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& voice->isPlayingChannel (midiChannel))
for (auto* voice : voices)
if (voice->getCurrentlyPlayingNote() == midiNoteNumber && voice->isPlayingChannel (midiChannel))
stopVoice (voice, 1.0f, true);
}
startVoice (findFreeVoice (sound, midiChannel, midiNoteNumber, shouldStealNotes),
sound, midiChannel, midiNoteNumber, velocity);
@@ -337,7 +304,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
voice->currentPlayingMidiChannel = midiChannel;
voice->noteOnTime = ++lastNoteOnCounter;
voice->currentlyPlayingSound = sound;
voice->keyIsDown = true;
voice->setKeyDown (true);
voice->sostenutoPedalDown = false;
voice->sustainPedalDown = sustainPedalsDown[midiChannel];
@@ -363,10 +330,8 @@ void Synthesiser::noteOff (const int midiChannel,
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
for (auto* voice : voices)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& voice->isPlayingChannel (midiChannel))
{
@@ -377,7 +342,7 @@ void Synthesiser::noteOff (const int midiChannel,
{
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]);
voice->keyIsDown = false;
voice->setKeyDown (false);
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown))
stopVoice (voice, velocity, allowTailOff);
@@ -391,13 +356,9 @@ void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff)
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
voice->stopNote (1.0f, allowTailOff);
}
sustainPedalsDown.clear();
}
@@ -406,13 +367,9 @@ void Synthesiser::handlePitchWheel (const int midiChannel, const int wheelValue)
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
voice->pitchWheelMoved (wheelValue);
}
}
void Synthesiser::handleController (const int midiChannel,
@@ -429,40 +386,28 @@ void Synthesiser::handleController (const int midiChannel,
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
voice->controllerMoved (controllerNumber, controllerValue);
}
}
void Synthesiser::handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue)
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)))
voice->aftertouchChanged (aftertouchValue);
}
}
void Synthesiser::handleChannelPressure (int midiChannel, int channelPressureValue)
{
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
voice->channelPressureChanged (channelPressureValue);
}
}
void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
@@ -474,25 +419,19 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
{
sustainPedalsDown.setBit (midiChannel);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown())
voice->sustainPedalDown = true;
}
}
else
{
for (int i = voices.size(); --i >= 0;)
for (auto* voice : voices)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel))
{
voice->sustainPedalDown = false;
if (! voice->isKeyDown())
if (! (voice->isKeyDown() || voice->isSostenutoPedalDown()))
stopVoice (voice, 1.0f, true);
}
}
@@ -506,10 +445,8 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
jassert (midiChannel > 0 && midiChannel <= 16);
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
for (auto* voice : voices)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel))
{
if (isDown)
@@ -539,13 +476,9 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
{
const ScopedLock sl (lock);
for (int i = 0; i < voices.size(); ++i)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
for (auto* voice : voices)
if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay))
return voice;
}
if (stealIfNoneAvailable)
return findVoiceToSteal (soundToPlay, midiChannel, midiNoteNumber);
@@ -569,7 +502,7 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
// - Protect the lowest & topmost notes, even if sustained, but not if they've been released.
// apparently you are trying to render audio without having any voices...
jassert (voices.size() > 0);
jassert (! voices.isEmpty());
// These are the voices we want to protect (ie: only steal if unavoidable)
SynthesiserVoice* low = nullptr; // Lowest sounding note, might be sustained, but NOT in release phase
@@ -579,10 +512,8 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
Array<SynthesiserVoice*> usableVoices;
usableVoices.ensureStorageAllocated (voices.size());
for (int i = 0; i < voices.size(); ++i)
for (auto* voice : voices)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->canPlaySound (soundToPlay))
{
jassert (voice->isVoiceActive()); // We wouldn't be here otherwise
@@ -592,7 +523,7 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
if (! voice->isPlayingButReleased()) // Don't protect released notes
{
const int note = voice->getCurrentlyPlayingNote();
auto note = voice->getCurrentlyPlayingNote();
if (low == nullptr || note < low->getCurrentlyPlayingNote())
low = voice;
@@ -607,43 +538,25 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
if (top == low)
top = nullptr;
const int numUsableVoices = usableVoices.size();
// The oldest note that's playing with the target pitch is ideal..
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
for (auto* voice : usableVoices)
if (voice->getCurrentlyPlayingNote() == midiNoteNumber)
return voice;
}
// Oldest voice that has been released (no finger on it and not held by sustain pedal)
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
for (auto* voice : usableVoices)
if (voice != low && voice != top && voice->isPlayingButReleased())
return voice;
}
// Oldest voice that doesn't have a finger on it:
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
for (auto* voice : usableVoices)
if (voice != low && voice != top && ! voice->isKeyDown())
return voice;
}
// Oldest voice that isn't protected
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
for (auto* voice : usableVoices)
if (voice != low && voice != top)
return voice;
}
// We've only got "protected" voices now: lowest note takes priority
jassert (low != nullptr);


+ 16
- 9
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -182,6 +182,8 @@ public:
virtual void renderNextBlock (AudioBuffer<float>& outputBuffer,
int startSample,
int numSamples) = 0;
/** A double-precision version of renderNextBlock() */
virtual void renderNextBlock (AudioBuffer<double>& outputBuffer,
int startSample,
int numSamples);
@@ -214,6 +216,11 @@ public:
*/
bool isKeyDown() const noexcept { return keyIsDown; }
/** Allows you to modify the flag indicating that the key that triggered this voice is still held down.
@see isKeyDown
*/
void setKeyDown (bool isNowDown) noexcept { keyIsDown = isNowDown; }
/** Returns true if the sustain pedal is currently active for this voice. */
bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
@@ -249,11 +256,11 @@ private:
//==============================================================================
friend class Synthesiser;
double currentSampleRate;
int currentlyPlayingNote, currentPlayingMidiChannel;
uint32 noteOnTime;
double currentSampleRate = 44100.0;
int currentlyPlayingNote = -1, currentPlayingMidiChannel = 0;
uint32 noteOnTime = 0;
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sustainPedalDown, sostenutoPedalDown;
bool keyIsDown = false, sustainPedalDown = false, sostenutoPedalDown = false;
AudioBuffer<float> tempBuffer;
@@ -615,11 +622,11 @@ private:
int startSample,
int numSamples);
//==============================================================================
double sampleRate;
uint32 lastNoteOnCounter;
int minimumSubBlockSize;
bool subBlockSubdivisionIsStrict;
bool shouldStealNotes;
double sampleRate = 0;
uint32 lastNoteOnCounter = 0;
int minimumSubBlockSize = 32;
bool subBlockSubdivisionIsStrict = false;
bool shouldStealNotes = true;
BigInteger sustainPedalsDown;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE


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

@@ -651,11 +651,16 @@ public:
{
OpenSLSession::stop();
while (! guard.compareAndSetBool (1, 0))
Thread::sleep (1);
if (inputChannels > 0)
recorder->setState (false);
if (outputChannels > 0)
player->setState (false);
guard.set (0);
}
bool setAudioPreprocessingEnabled (bool shouldEnable) override


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

@@ -576,7 +576,13 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead,
&hostUrl,
&dataSize);
if (err == noErr)
[[UIApplication sharedApplication] openURL:(NSURL*)hostUrl];
{
#if (! defined __IPHONE_OS_VERSION_MIN_REQUIRED) || (! defined __IPHONE_10_0) || (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)
[[UIApplication sharedApplication] openURL: (NSURL*)hostUrl];
#else
[[UIApplication sharedApplication] openURL: (NSURL*)hostUrl options: @{} completionHandler: nil];
#endif
}
}
//==============================================================================


+ 41
- 13
libs/juce/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp View File

@@ -357,7 +357,8 @@ public:
actualBufferSize (0),
bytesPerSample (0),
bytesPerFrame (0),
sampleRateHasChanged (false)
sampleRateHasChanged (false),
shouldClose (false)
{
clientEvent = CreateEvent (nullptr, false, false, nullptr);
@@ -468,6 +469,11 @@ public:
sampleRateHasChanged = true;
}
void deviceBecameInactive()
{
shouldClose = true;
}
//==============================================================================
ComSmartPtr<IMMDevice> device;
ComSmartPtr<IAudioClient> client;
@@ -482,7 +488,7 @@ public:
Array<int> channelMaps;
UINT32 actualBufferSize;
int bytesPerSample, bytesPerFrame;
bool sampleRateHasChanged;
bool sampleRateHasChanged, shouldClose;
virtual void updateFormat (bool isFloat) = 0;
@@ -498,10 +504,17 @@ private:
JUCE_COMRESULT OnSimpleVolumeChanged (float, BOOL, LPCGUID) { return S_OK; }
JUCE_COMRESULT OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) { return S_OK; }
JUCE_COMRESULT OnGroupingParamChanged (LPCGUID, LPCGUID) { return S_OK; }
JUCE_COMRESULT OnStateChanged (AudioSessionState) { return S_OK; }
JUCE_COMRESULT OnStateChanged(AudioSessionState state)
{
if (state == AudioSessionStateInactive || state == AudioSessionStateExpired)
owner.deviceBecameInactive();
return S_OK;
}
JUCE_COMRESULT OnSessionDisconnected (AudioSessionDisconnectReason reason)
{
Logger::writeToLog("OnSessionDisconnected");
if (reason == DisconnectReasonFormatChanged)
owner.deviceSampleRateChanged();
@@ -969,7 +982,8 @@ public:
isStarted (false),
currentBufferSizeSamples (0),
currentSampleRate (0),
callback (nullptr)
callback (nullptr),
deviceBecameInactive (false)
{
}
@@ -1107,6 +1121,8 @@ public:
if (inputDevice != nullptr) ResetEvent (inputDevice->clientEvent);
if (outputDevice != nullptr) ResetEvent (outputDevice->clientEvent);
deviceBecameInactive = false;
startThread (8);
Thread::sleep (5);
@@ -1226,8 +1242,14 @@ public:
while (! threadShouldExit())
{
if (inputDevice != nullptr)
if (outputDevice != nullptr && outputDevice->shouldClose)
deviceBecameInactive = true;
if (inputDevice != nullptr && ! deviceBecameInactive)
{
if (inputDevice->shouldClose)
deviceBecameInactive = true;
if (outputDevice == nullptr)
{
if (WaitForSingleObject (inputDevice->clientEvent, 1000) == WAIT_TIMEOUT)
@@ -1253,6 +1275,7 @@ public:
}
}
if (! deviceBecameInactive)
{
const ScopedTryLock sl (startStopLock);
@@ -1263,7 +1286,7 @@ public:
outs.clear();
}
if (outputDevice != nullptr)
if (outputDevice != nullptr && !deviceBecameInactive)
{
// Note that this function is handed the input device so it can check for the event and make sure
// the input reservoir is filled up correctly even when bufferSize > device actualBufferSize
@@ -1276,7 +1299,7 @@ public:
}
}
if (sampleRateHasChanged)
if (sampleRateHasChanged || deviceBecameInactive)
{
triggerAsyncUpdate();
break; // Quit the thread... will restart it later!
@@ -1303,7 +1326,7 @@ private:
bool isOpen_, isStarted;
int currentBufferSizeSamples;
double currentSampleRate;
bool sampleRateChangedByOutput;
bool sampleRateChangedByOutput, deviceBecameInactive;
AudioIODeviceCallback* callback;
CriticalSection startStopLock;
@@ -1354,12 +1377,17 @@ private:
outputDevice = nullptr;
inputDevice = nullptr;
initialise();
open (lastKnownInputChannels, lastKnownOutputChannels,
getChangedSampleRate(), currentBufferSizeSamples);
// sample rate change
if (! deviceBecameInactive)
{
initialise();
open (lastKnownInputChannels, lastKnownOutputChannels,
getChangedSampleRate(), currentBufferSizeSamples);
start (callback);
start (callback);
}
}
double getChangedSampleRate() const
@@ -1481,7 +1509,7 @@ private:
HRESULT STDMETHODCALLTYPE OnDeviceAdded (LPCWSTR) { return notify(); }
HRESULT STDMETHODCALLTYPE OnDeviceRemoved (LPCWSTR) { return notify(); }
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged (LPCWSTR, DWORD) { return notify(); }
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR, DWORD) { return notify(); }
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged (EDataFlow, ERole, LPCWSTR) { return notify(); }
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) { return notify(); }


+ 6
- 15
libs/juce/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp View File

@@ -619,8 +619,7 @@ public:
for (auto tagEntry : knownTags)
{
AudioChannelLayout layout { tagEntry.tag };
auto labels = CoreAudioLayouts::fromCoreAudio (layout);
auto labels = CoreAudioLayouts::fromCoreAudio (tagEntry.tag);
expect (! labels.isDiscreteLayout(), String ("Tag \"") + String (tagEntry.name) + "\" is not handled by JUCE");
}
@@ -631,8 +630,7 @@ public:
for (auto tagEntry : knownTags)
{
AudioChannelLayout layout { tagEntry.tag };
auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout);
auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
expect (labels.size() == (tagEntry.tag & 0xffff), String ("Tag \"") + String (tagEntry.name) + "\" has incorrect channel count");
}
@@ -643,8 +641,7 @@ public:
for (auto tagEntry : knownTags)
{
AudioChannelLayout layout { tagEntry.tag };
auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout);
auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
labels.sort();
for (int i = 0; i < (labels.size() - 1); ++i)
@@ -657,13 +654,9 @@ public:
beginTest ("CA speaker list and juce layouts are consistent");
for (auto tagEntry : knownTags)
{
AudioChannelLayout layout { tagEntry.tag };
expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getCoreAudioLayoutChannels (layout))
== CoreAudioLayouts::fromCoreAudio (layout),
expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag))
== CoreAudioLayouts::fromCoreAudio (tagEntry.tag),
String ("Tag \"") + String (tagEntry.name) + "\" is not converted consistantly by JUCE");
}
}
{
@@ -674,9 +667,7 @@ public:
if (tagEntry.equivalentChannelSet.isDisabled())
continue;
AudioChannelLayout layout { tagEntry.tag };
expect (CoreAudioLayouts::fromCoreAudio (layout) == tagEntry.equivalentChannelSet,
expect (CoreAudioLayouts::fromCoreAudio (tagEntry.tag) == tagEntry.equivalentChannelSet,
String ("Documentation for tag \"") + String (tagEntry.name) + "\" is incorrect");
}
}


+ 7
- 0
libs/juce/source/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp View File

@@ -942,6 +942,13 @@ namespace AAXClasses
{
if (type == AAX_eNotificationEvent_EnteringOfflineMode) pluginInstance->setNonRealtime (true);
if (type == AAX_eNotificationEvent_ExitingOfflineMode) pluginInstance->setNonRealtime (false);
if (type == AAX_eNotificationEvent_TrackNameChanged && data != nullptr)
{
AudioProcessor::TrackProperties props;
props.name = static_cast<const AAX_IString*> (data)->Get();
pluginInstance->updateTrackProperties (props);
}
return AAX_CEffectParameters::NotificationReceived (type, data, size);
}


+ 23
- 7
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -147,6 +147,8 @@ public:
channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter);
#endif
AddPropertyListener (kAudioUnitProperty_ContextName, auPropertyListenerDispatcher, this);
totalInChannels = juceFilter->getTotalNumInputChannels();
totalOutChannels = juceFilter->getTotalNumOutputChannels();
@@ -1818,12 +1820,7 @@ private:
if (numChannels != tagNumChannels)
return kAudioUnitErr_FormatNotSupported;
AudioChannelLayout layout;
zerostruct (layout);
layout.mChannelLayoutTag = currentLayoutTag;
requestedBuses.add (CoreAudioLayouts::fromCoreAudio (layout));
requestedBuses.add (CoreAudioLayouts::fromCoreAudio (currentLayoutTag));
}
}
@@ -1909,7 +1906,7 @@ private:
auto& knownTags = CoreAudioLayouts::getKnownCoreAudioTags();
for (auto tag : knownTags)
if (bus->isLayoutSupported (CoreAudioLayouts::fromCoreAudio (AudioChannelLayout {tag})))
if (bus->isLayoutSupported (CoreAudioLayouts::fromCoreAudio (tag)))
tags.addIfNotAlreadyThere (tag);
#endif
@@ -1961,6 +1958,25 @@ private:
return (getHostType().isLogic() ? 8 : 64);
}
//==============================================================================
void auPropertyListener (AudioUnitPropertyID propId, AudioUnitScope scope, AudioUnitElement)
{
if (scope == kAudioUnitScope_Global && propId == kAudioUnitProperty_ContextName
&& juceFilter != nullptr && mContextName != nullptr)
{
AudioProcessor::TrackProperties props;
props.name = String::fromCFString (mContextName);
juceFilter->updateTrackProperties (props);
}
}
static void auPropertyListenerDispatcher (void* inRefCon, AudioUnit, AudioUnitPropertyID propId,
AudioUnitScope scope, AudioUnitElement element)
{
static_cast<JuceAU*> (inRefCon)->auPropertyListener (propId, scope, element);
}
JUCE_DECLARE_NON_COPYABLE (JuceAU)
};


+ 301
- 141
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm View File

@@ -37,12 +37,20 @@
#if (! defined MAC_OS_X_VERSION_MIN_REQUIRED) || (! defined MAC_OS_X_VERSION_10_11) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)
#error AUv3 needs Deployment Target OS X 10.11 or higher to compile
#endif
#if (defined MAC_OS_X_VERSION_10_13) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13)
#define JUCE_AUV3_MIDI_OUTPUT_SUPPORTED 1
#define JUCE_AUV3_VIEW_CONFIG_SUPPORTED 1
#endif
#endif
#if JUCE_IOS
#if (! defined __IPHONE_OS_VERSION_MIN_REQUIRED) || (! defined __IPHONE_9_0) || (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
#error AUv3 needs Deployment Target iOS 9.0 or higher to compile
#endif
#if (defined __IPHONE_11_0) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0)
#define JUCE_AUV3_MIDI_OUTPUT_SUPPORTED 1
#define JUCE_AUV3_VIEW_CONFIG_SUPPORTED 1
#endif
#endif
#ifndef __OBJC2__
@@ -97,6 +105,15 @@ struct AudioProcessorHolder : public ReferenceCountedObject
AudioProcessor* operator->() noexcept { return processor; }
AudioProcessor* get() noexcept { return processor; }
struct ViewConfig
{
double width;
double height;
bool hostHasMIDIController;
};
ScopedPointer<ViewConfig> viewConfiguration;
typedef ReferenceCountedObjectPtr<AudioProcessorHolder> Ptr;
private:
@@ -121,8 +138,7 @@ public:
error: error
juceClass: this])
#pragma clang diagnostic pop
{
}
{}
JuceAudioUnitv3Base (AUAudioUnit* audioUnit) : au (audioUnit)
{
@@ -134,39 +150,14 @@ public:
//==============================================================================
AUAudioUnit* getAudioUnit() noexcept { return au; }
virtual int getVirtualMIDICableCount() { return 0; }
virtual void reset() {}
virtual bool shouldChangeToFormat (AVAudioFormat* format, AUAudioUnitBus* bus)
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
return (ObjCMsgSendSuper<BOOL, AVAudioFormat*,AUAudioUnitBus* > (&s, @selector (shouldChangeToFormat:forBus:), format, bus) == YES);
}
virtual AUAudioUnitPreset* getCurrentPreset() { return nullptr; }
virtual void setCurrentPreset(AUAudioUnitPreset*) {}
virtual NSTimeInterval getLatency() { return 0.0; }
virtual NSTimeInterval getTailTime() { return 0.0; }
virtual bool getCanProcessInPlace() { return false; }
virtual bool getRenderingOffline() { return false; }
//==============================================================================
virtual AUAudioUnitBusArray* getInputBusses() = 0;
virtual AUAudioUnitBusArray* getOutputBusses() = 0;
virtual AUParameterTree* getParameterTree() = 0;
virtual AUInternalRenderBlock getInternalRenderBlock() = 0;
virtual void setRenderingOffline (bool offline) = 0;
virtual NSArray<NSNumber*> *getChannelCapabilities() = 0;
virtual void reset() = 0;
//==============================================================================
virtual NSArray<NSNumber*>* parametersForOverviewWithCount (int)
{
return [NSArray<NSNumber*> array];
}
virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets()
{
return [NSArray<AUAudioUnitPreset*> array];
}
virtual AUAudioUnitPreset* getCurrentPreset() = 0;
virtual void setCurrentPreset(AUAudioUnitPreset*) = 0;
virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets() = 0;
virtual NSDictionary<NSString*, id>* getFullState()
{
@@ -180,6 +171,34 @@ public:
ObjCMsgSendSuper<void, NSDictionary<NSString*, id>*> (&s, @selector (setFullState:), state);
}
virtual AUParameterTree* getParameterTree() = 0;
virtual NSArray<NSNumber*>* parametersForOverviewWithCount (int) = 0;
//==============================================================================
virtual NSTimeInterval getLatency() = 0;
virtual NSTimeInterval getTailTime() = 0;
//==============================================================================
virtual AUAudioUnitBusArray* getInputBusses() = 0;
virtual AUAudioUnitBusArray* getOutputBusses() = 0;
virtual NSArray<NSNumber*>* getChannelCapabilities() = 0;
virtual bool shouldChangeToFormat (AVAudioFormat*, AUAudioUnitBus*) = 0;
//==============================================================================
virtual int getVirtualMIDICableCount() = 0;
virtual bool getSupportsMPE() = 0;
virtual NSArray<NSString*>* getMIDIOutputNames() = 0;
//==============================================================================
virtual AUInternalRenderBlock getInternalRenderBlock() = 0;
virtual bool getCanProcessInPlace() { return false; }
virtual bool getRenderingOffline() = 0;
virtual void setRenderingOffline (bool offline) = 0;
//==============================================================================
virtual NSString* getContextName() const = 0;
virtual void setContextName (NSString*) = 0;
virtual bool allocateRenderResourcesAndReturnError (NSError **outError)
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
@@ -192,6 +211,12 @@ public:
ObjCMsgSendSuper<void> (&s, @selector (deallocateRenderResources));
}
//==============================================================================
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
virtual NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>*) = 0;
virtual void selectViewConfiguration (AUAudioUnitViewConfiguration*) = 0;
#endif
private:
struct Class : public ObjCClass<AUAudioUnit>
{
@@ -212,31 +237,55 @@ private:
@encode (AudioComponentDescription),
@encode (AudioComponentInstantiationOptions), "^@");
addMethod (@selector (dealloc), dealloc, "v@:");
addMethod (@selector (inputBusses), getInputBusses, "@@:");
addMethod (@selector (outputBusses), getOutputBusses, "@@:");
addMethod (@selector (parameterTree), getParameterTree, "@@:");
addMethod (@selector (deallocateRenderResources), deallocateRenderResources, "v@:");
addMethod (@selector (reset), reset, "v@:");
addMethod (@selector (shouldChangeToFormat:forBus:), shouldChangeToFormat, "B@:@@");
addMethod (@selector (factoryPresets), getFactoryPresets, "@@:");
addMethod (@selector (currentPreset), getCurrentPreset, "@@:");
addMethod (@selector (setCurrentPreset:), setCurrentPreset, "v@:@");
addMethod (@selector (fullState), getFullState, "@@:");
addMethod (@selector (setFullState:), setFullState, "v@:@");
addMethod (@selector (channelCapabilities), getChannelCapabilities, "@@:");
addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError, "B@:^@");
addMethod (@selector (dealloc), dealloc, "v@:");
//==============================================================================
addMethod (@selector (reset), reset, "v@:");
//==============================================================================
addMethod (@selector (currentPreset), getCurrentPreset, "@@:");
addMethod (@selector (setCurrentPreset:), setCurrentPreset, "v@:@");
addMethod (@selector (factoryPresets), getFactoryPresets, "@@:");
addMethod (@selector (fullState), getFullState, "@@:");
addMethod (@selector (setFullState:), setFullState, "v@:@");
addMethod (@selector (parameterTree), getParameterTree, "@@:");
addMethod (@selector (parametersForOverviewWithCount:), parametersForOverviewWithCount, "@@:", @encode (NSInteger));
//==============================================================================
addMethod (@selector (latency), getLatency, @encode (NSTimeInterval), "@:");
addMethod (@selector (tailTime), getTailTime, @encode (NSTimeInterval), "@:");
//==============================================================================
addMethod (@selector (inputBusses), getInputBusses, "@@:");
addMethod (@selector (outputBusses), getOutputBusses, "@@:");
addMethod (@selector (channelCapabilities), getChannelCapabilities, "@@:");
addMethod (@selector (shouldChangeToFormat:forBus:), shouldChangeToFormat, "B@:@@");
//==============================================================================
addMethod (@selector (virtualMIDICableCount), getVirtualMIDICableCount, @encode (NSInteger), "@:");
addMethod (@selector (supportsMPE), getSupportsMPE, @encode (BOOL), "@:");
#if JUCE_AUV3_MIDI_OUTPUT_SUPPORTED
addMethod (@selector (MIDIOutputNames), getMIDIOutputNames, "@@:");
#endif
//==============================================================================
addMethod (@selector (internalRenderBlock), getInternalRenderBlock, @encode (AUInternalRenderBlock), "@:");
addMethod (@selector (canProcessInPlace), getCanProcessInPlace, @encode (BOOL), "@:");
addMethod (@selector (isRenderingOffline), getRenderingOffline, @encode (BOOL), "@:");
addMethod (@selector (setRenderingOffline:), setRenderingOffline, "v@:", @encode (BOOL));
addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError, "B@:^@");
addMethod (@selector (deallocateRenderResources), deallocateRenderResources, "v@:");
//==============================================================================
addMethod (@selector (contextName), getContextName, "@@:");
addMethod (@selector (setContextName:), setContextName, "v@:@");
addMethod (@selector (internalRenderBlock), getInternalRenderBlock, @encode (AUInternalRenderBlock), "@:");
addMethod (@selector (virtualMIDICableCount), getVirtualMIDICableCount, @encode (NSInteger), "@:");
addMethod (@selector (latency), getLatency, @encode (NSTimeInterval), "@:");
addMethod (@selector (tailTime), getTailTime, @encode (NSTimeInterval), "@:");
addMethod (@selector (canProcessInPlace), getCanProcessInPlace, @encode (BOOL), "@:");
addMethod (@selector (isRenderingOffline), getRenderingOffline, @encode (BOOL), "@:");
//==============================================================================
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
addMethod (@selector (supportedViewConfigurations:), getSupportedViewConfigurations, "@@:@");
addMethod (@selector (selectViewConfiguration:), selectViewConfiguration, "v@:@");
#endif
registerClass();
}
@@ -274,27 +323,51 @@ private:
}
static void dealloc (id self, SEL) { delete _this (self); }
static AUAudioUnitBusArray* getInputBusses (id self, SEL) { return _this (self)->getInputBusses(); }
static AUAudioUnitBusArray* getOutputBusses (id self, SEL) { return _this (self)->getOutputBusses(); }
static AUParameterTree* getParameterTree (id self, SEL) { return _this (self)->getParameterTree(); }
static AUInternalRenderBlock getInternalRenderBlock (id self, SEL) { return _this (self)->getInternalRenderBlock(); }
static BOOL allocateRenderResourcesAndReturnError (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; }
static void deallocateRenderResources (id self, SEL) { _this (self)->deallocateRenderResources(); }
//==============================================================================
static void reset (id self, SEL) { _this (self)->reset(); }
static NSInteger getVirtualMIDICableCount (id self, SEL) { return _this (self)->getVirtualMIDICableCount(); }
static BOOL shouldChangeToFormat (id self, SEL, AVAudioFormat* format, AUAudioUnitBus* bus) { return _this (self)->shouldChangeToFormat (format, bus) ? YES : NO; }
static NSArray<NSNumber*>* parametersForOverviewWithCount (id self, SEL, NSInteger count) { return _this (self)->parametersForOverviewWithCount (static_cast<int> (count)); }
static NSArray<AUAudioUnitPreset*>* getFactoryPresets (id self, SEL) { return _this (self)->getFactoryPresets(); }
//==============================================================================
static AUAudioUnitPreset* getCurrentPreset (id self, SEL) { return _this (self)->getCurrentPreset(); }
static void setCurrentPreset (id self, SEL, AUAudioUnitPreset* preset) { return _this (self)->setCurrentPreset (preset); }
static NSArray<AUAudioUnitPreset*>* getFactoryPresets (id self, SEL) { return _this (self)->getFactoryPresets(); }
static NSDictionary<NSString*, id>* getFullState (id self, SEL) { return _this (self)->getFullState(); }
static void setFullState (id self, SEL, NSDictionary<NSString *, id>* state) { return _this (self)->setFullState (state); }
static AUParameterTree* getParameterTree (id self, SEL) { return _this (self)->getParameterTree(); }
static NSArray<NSNumber*>* parametersForOverviewWithCount (id self, SEL, NSInteger count) { return _this (self)->parametersForOverviewWithCount (static_cast<int> (count)); }
//==============================================================================
static NSTimeInterval getLatency (id self, SEL) { return _this (self)->getLatency(); }
static NSTimeInterval getTailTime (id self, SEL) { return _this (self)->getTailTime(); }
//==============================================================================
static AUAudioUnitBusArray* getInputBusses (id self, SEL) { return _this (self)->getInputBusses(); }
static AUAudioUnitBusArray* getOutputBusses (id self, SEL) { return _this (self)->getOutputBusses(); }
static NSArray<NSNumber*>* getChannelCapabilities (id self, SEL) { return _this (self)->getChannelCapabilities(); }
static BOOL shouldChangeToFormat (id self, SEL, AVAudioFormat* format, AUAudioUnitBus* bus) { return _this (self)->shouldChangeToFormat (format, bus) ? YES : NO; }
//==============================================================================
static NSInteger getVirtualMIDICableCount (id self, SEL) { return _this (self)->getVirtualMIDICableCount(); }
static BOOL getSupportsMPE (id self, SEL) { return _this (self)->getSupportsMPE() ? YES : NO; }
static NSArray<NSString*>* getMIDIOutputNames (id self, SEL) { return _this (self)->getMIDIOutputNames(); }
//==============================================================================
static AUInternalRenderBlock getInternalRenderBlock (id self, SEL) { return _this (self)->getInternalRenderBlock(); }
static BOOL getCanProcessInPlace (id self, SEL) { return _this (self)->getCanProcessInPlace() ? YES : NO; }
static BOOL getRenderingOffline (id self, SEL) { return _this (self)->getRenderingOffline() ? YES : NO; }
static void setRenderingOffline (id self, SEL, BOOL renderingOffline) { _this (self)->setRenderingOffline (renderingOffline); }
static NSArray<NSNumber*>* getChannelCapabilities (id self, SEL) { return _this (self)->getChannelCapabilities(); }
static BOOL allocateRenderResourcesAndReturnError (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; }
static void deallocateRenderResources (id self, SEL) { _this (self)->deallocateRenderResources(); }
//==============================================================================
static NSString* getContextName (id self, SEL) { return _this (self)->getContextName(); }
static void setContextName (id self, SEL, NSString* str) { return _this (self)->setContextName (str); }
//==============================================================================
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
static NSIndexSet* getSupportedViewConfigurations (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs) { return _this (self)->getSupportedViewConfigurations (configs); }
static void selectViewConfiguration (id self, SEL, AUAudioUnitViewConfiguration* config) { _this (self)->selectViewConfiguration (config); }
#endif
};
static JuceAudioUnitv3Base* create (AUAudioUnit*, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**);
@@ -410,16 +483,14 @@ public:
addAudioUnitBusses (false);
}
//==============================================================================
AudioProcessor& getAudioProcessor() const noexcept { return **processorHolder; }
AUAudioUnitBusArray* getInputBusses() override { return inputBusses; }
AUAudioUnitBusArray* getOutputBusses() override { return outputBusses; }
AUParameterTree* getParameterTree() override { return paramTree; }
AUInternalRenderBlock getInternalRenderBlock() override { return internalRenderBlock; }
NSArray<AUAudioUnitPreset*>* getFactoryPresets() override { return factoryPresets; }
bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); }
void setRenderingOffline (bool offline) override { getAudioProcessor().setNonRealtime (offline); }
NSArray<NSNumber*>* getChannelCapabilities() override { return channelCapabilities; }
//==============================================================================
void reset() override
{
midiMessages.clear();
lastTimeStamp.mSampleTime = std::numeric_limits<Float64>::max();
}
//==============================================================================
AUAudioUnitPreset* getCurrentPreset() override
@@ -442,7 +513,11 @@ public:
getAudioProcessor().setCurrentProgram (idx);
}
//==============================================================================
NSArray<AUAudioUnitPreset*>* getFactoryPresets() override
{
return factoryPresets;
}
NSDictionary<NSString*, id>* getFullState() override
{
NSMutableDictionary<NSString*, id>* retval = [[NSMutableDictionary<NSString*, id> alloc] init];
@@ -508,7 +583,11 @@ public:
[modifiedState release];
}
//==============================================================================
AUParameterTree* getParameterTree() override
{
return paramTree;
}
NSArray<NSNumber*>* parametersForOverviewWithCount (int count) override
{
const int n = static_cast<int> ([overviewParams count]);
@@ -522,6 +601,68 @@ public:
return [retval autorelease];
}
//==============================================================================
NSTimeInterval getLatency() override
{
auto& p = getAudioProcessor();
return p.getLatencySamples() / p.getSampleRate();
}
NSTimeInterval getTailTime() override
{
return getAudioProcessor().getTailLengthSeconds();
}
//==============================================================================
AUAudioUnitBusArray* getInputBusses() override { return inputBusses; }
AUAudioUnitBusArray* getOutputBusses() override { return outputBusses; }
NSArray<NSNumber*>* getChannelCapabilities() override { return channelCapabilities; }
bool shouldChangeToFormat (AVAudioFormat* format, AUAudioUnitBus* auBus) override
{
const bool isInput = ([auBus busType] == AUAudioUnitBusTypeInput);
const int busIdx = static_cast<int> ([auBus index]);
const int newNumChannels = static_cast<int> ([format channelCount]);
AudioProcessor& processor = getAudioProcessor();
if (AudioProcessor::Bus* bus = processor.getBus (isInput, busIdx))
{
#ifdef JucePlugin_PreferredChannelConfigurations
ignoreUnused (bus);
short configs[][2] = {JucePlugin_PreferredChannelConfigurations};
if (! AudioUnitHelpers::isLayoutSupported (processor, isInput, busIdx, newNumChannels, configs))
return false;
#else
const AVAudioChannelLayout* layout = [format channelLayout];
const AudioChannelLayoutTag layoutTag = (layout != nullptr ? [layout layoutTag] : 0);
if (layoutTag != 0)
{
AudioChannelSet newLayout = CoreAudioLayouts::fromCoreAudio (layoutTag);
if (newLayout.size() != newNumChannels)
return false;
if (! bus->isLayoutSupported (newLayout))
return false;
}
else
{
if (! bus->isNumberOfChannelsSupported (newNumChannels))
return false;
}
#endif
return true;
}
return false;
}
//==============================================================================
int getVirtualMIDICableCount() override
{
#if JucePlugin_WantsMidiInput
@@ -531,6 +672,38 @@ public:
#endif
}
bool getSupportsMPE() override
{
return getAudioProcessor().supportsMPE();
}
NSArray<NSString*>* getMIDIOutputNames() override
{
#if JucePlugin_ProducesMidiOutput
return @[@"MIDI Out"];
#else
return @[];
#endif
}
//==============================================================================
AUInternalRenderBlock getInternalRenderBlock() override { return internalRenderBlock; }
bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); }
void setRenderingOffline (bool offline) override { getAudioProcessor().setNonRealtime (offline); }
//==============================================================================
NSString* getContextName() const override { return juceStringToNS (contextName); }
void setContextName (NSString* str) override
{
if (str != nullptr)
{
AudioProcessor::TrackProperties props;
props.name = nsStringToJuce (str);
getAudioProcessor().updateTrackProperties (props);
}
}
//==============================================================================
bool allocateRenderResourcesAndReturnError (NSError **outError) override
{
@@ -563,13 +736,7 @@ public:
const AudioChannelLayoutTag layoutTag = (layout != nullptr ? [layout layoutTag] : 0);
if (layoutTag != 0)
{
AudioChannelLayout caLayout;
zerostruct (caLayout);
caLayout.mChannelLayoutTag = layoutTag;
newLayout = CoreAudioLayouts::fromCoreAudio (caLayout);
}
newLayout = CoreAudioLayouts::fromCoreAudio (layoutTag);
else
newLayout = bus->supportedLayoutWithChannels (static_cast<int> ([format channelCount]));
@@ -641,60 +808,45 @@ public:
JuceAudioUnitv3Base::deallocateRenderResources();
}
void reset() override
{
midiMessages.clear();
lastTimeStamp.mSampleTime = std::numeric_limits<Float64>::max();
}
//==============================================================================
bool shouldChangeToFormat (AVAudioFormat* format, AUAudioUnitBus* auBus) override
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>* configs) override
{
const bool isInput = ([auBus busType] == AUAudioUnitBusTypeInput);
const int busIdx = static_cast<int> ([auBus index]);
const int newNumChannels = static_cast<int> ([format channelCount]);
auto supportedViewIndecies = [[NSMutableIndexSet alloc] init];
auto n = [configs count];
AudioProcessor& processor = getAudioProcessor();
if (AudioProcessor::Bus* bus = processor.getBus (isInput, busIdx))
if (auto* editor = getAudioProcessor().createEditorIfNeeded())
{
#ifdef JucePlugin_PreferredChannelConfigurations
ignoreUnused (bus);
short configs[][2] = {JucePlugin_PreferredChannelConfigurations};
// If you hit this assertion then your plug-in's editor is reporting that it doesn't support
// any host MIDI controller configurations!
jassert (editor->supportsHostMIDIControllerPresence (true) || editor->supportsHostMIDIControllerPresence (false));
if (! AudioUnitHelpers::isLayoutSupported (processor, isInput, busIdx, newNumChannels, configs))
return false;
#else
const AVAudioChannelLayout* layout = [format channelLayout];
const AudioChannelLayoutTag layoutTag = (layout != nullptr ? [layout layoutTag] : 0);
if (layoutTag != 0)
{
AudioChannelLayout caLayout;
zerostruct (caLayout);
caLayout.mChannelLayoutTag = layoutTag;
AudioChannelSet newLayout = CoreAudioLayouts::fromCoreAudio (caLayout);
if (newLayout.size() != newNumChannels)
return false;
if (! bus->isLayoutSupported (newLayout))
return false;
}
else
for (auto i = 0u; i < n; ++i)
{
if (! bus->isNumberOfChannelsSupported (newNumChannels))
return false;
if (auto* viewConfiguration = [configs objectAtIndex:i])
{
if (editor->supportsHostMIDIControllerPresence ([viewConfiguration hostHasController] == YES))
{
auto* constrainer = editor->getConstrainer();
auto height = (int) [viewConfiguration height];
auto width = (int) [viewConfiguration width];
if (height <= constrainer->getMaximumHeight() && height >= constrainer->getMinimumHeight()
&& width <= constrainer->getMaximumWidth() && width >= constrainer->getMinimumWidth())
[supportedViewIndecies addIndex: i];
}
}
}
#endif
return true;
}
return false;
return [supportedViewIndecies autorelease];
}
void selectViewConfiguration (AUAudioUnitViewConfiguration* config) override
{
processorHolder->viewConfiguration = new AudioProcessorHolder::ViewConfig { [config width], [config height], [config hostHasController] == YES };
}
#endif
//==============================================================================
void audioProcessorChanged (AudioProcessor* processor) override
@@ -720,15 +872,6 @@ public:
}
}
//==============================================================================
NSTimeInterval getLatency() override
{
auto& p = getAudioProcessor();
return p.getLatencySamples() / p.getSampleRate();
}
NSTimeInterval getTailTime() override { return getAudioProcessor().getTailLengthSeconds(); }
//==============================================================================
bool getCurrentPosition (CurrentPositionInfo& info) override
{
@@ -802,6 +945,7 @@ public:
return true;
}
//==============================================================================
static void removeEditor (AudioProcessor& processor)
{
ScopedLock editorLock (processor.getCallbackLock());
@@ -818,7 +962,7 @@ private:
struct BusBuffer
{
BusBuffer (AUAudioUnitBus* bus, int maxFramesPerBuffer)
: auBus (bus), bufferList (nullptr),
: auBus (bus),
maxFrames (maxFramesPerBuffer),
numberOfChannels (static_cast<int> ([[auBus format] channelCount])),
isInterleaved ([[auBus format] isInterleaved])
@@ -893,7 +1037,7 @@ private:
private:
AUAudioUnitBus* auBus;
HeapBlock<char> bufferListStorage;
AudioBufferList* bufferList;
AudioBufferList* bufferList = nullptr;
int maxFrames, numberOfChannels;
bool isInterleaved;
AudioSampleBuffer scratchBuffer;
@@ -1048,6 +1192,7 @@ private:
static_cast<int> (maxFrames)));
}
//==============================================================================
void processEvents (const AURenderEvent *__nullable realtimeEventListHead, int numParams, AUEventSampleTime startTime)
{
for (const AURenderEvent* event = realtimeEventListHead; event != nullptr; event = event->head.next)
@@ -1175,6 +1320,17 @@ private:
// process audio
processBlock (audioBuffer.getBuffer (frameCount), midiMessages);
// send MIDI
#if JucePlugin_ProducesMidiOutput && JUCE_AUV3_MIDI_OUTPUT_SUPPORTED
auto midiOut = [au MIDIOutputEventBlock];
MidiMessage msg;
int samplePosition;
for (MidiBuffer::Iterator it (midiMessages); it.getNextEvent (msg, samplePosition);)
midiOut (samplePosition, 0, msg.getRawDataSize(), msg.getRawData());
#endif
midiMessages.clear();
}
@@ -1288,8 +1444,8 @@ private:
AUParameterObserverToken editorObserverToken;
ScopedPointer<AUParameterTree> paramTree;
ScopedPointer<NSMutableArray<NSNumber*> > overviewParams;
ScopedPointer<NSMutableArray<NSNumber*> > channelCapabilities;
ScopedPointer<NSMutableArray<NSNumber*>> overviewParams;
ScopedPointer<NSMutableArray<NSNumber*>> channelCapabilities;
ScopedPointer<NSMutableArray<AUAudioUnitPreset*> > factoryPresets;
@@ -1306,6 +1462,8 @@ private:
AudioTimeStamp lastTimeStamp;
CurrentPositionInfo lastAudioHead;
String contextName;
};
const double JuceAudioUnitv3::kDefaultSampleRate = 44100.0;
@@ -1320,9 +1478,8 @@ JuceAudioUnitv3Base* JuceAudioUnitv3Base::create (AUAudioUnit* audioUnit, AudioC
class JuceAUViewController
{
public:
JuceAUViewController (AUViewController<AUAudioUnitFactory>* p)
: myself (p), processorHolder (nullptr), preferredSize (1.0f, 1.0f)
: myself (p)
{
jassert (MessageManager::getInstance()->isThisTheMessageThread());
@@ -1370,6 +1527,9 @@ public:
{
if (AudioProcessorEditor* editor = getAudioProcessor().getActiveEditor())
{
if (processorHolder->viewConfiguration != nullptr)
editor->hostMIDIControllerIsAvailable (processorHolder->viewConfiguration->hostHasMIDIController);
editor->setBounds (convertToRectInt ([[myself view] bounds]));
if (JUCE_IOS_MAC_VIEW* peerView = [[[myself view] subviews] objectAtIndex: 0])
@@ -1433,8 +1593,8 @@ public:
private:
//==============================================================================
AUViewController<AUAudioUnitFactory>* myself;
AudioProcessorHolder::Ptr processorHolder;
Rectangle<int> preferredSize;
AudioProcessorHolder::Ptr processorHolder = nullptr;
Rectangle<int> preferredSize { 1, 1 };
//==============================================================================
AUAudioUnit* createAudioUnitOnMessageThread (const AudioComponentDescription& descr, NSError** error)


+ 1
- 11
libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -520,22 +520,12 @@ private:
if (newMidiDevices != lastMidiDevices)
{
for (auto& oldDevice : lastMidiDevices)
{
if (! newMidiDevices.contains (oldDevice))
{
deviceManager.setMidiInputEnabled (oldDevice, false);
deviceManager.removeMidiInputCallback (oldDevice, &player);
}
}
for (auto& newDevice : newMidiDevices)
{
if (! lastMidiDevices.contains (newDevice))
{
deviceManager.addMidiInputCallback (newDevice, &player);
deviceManager.setMidiInputEnabled (newDevice, true);
}
}
}
}
#endif
@@ -552,7 +542,7 @@ private:
that the other plugin wrappers use.
*/
class StandaloneFilterWindow : public DocumentWindow,
public ButtonListener // (can't use Button::Listener due to VC2005 bug)
public Button::Listener
{
public:
//==============================================================================


+ 3
- 1
libs/juce/source/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp View File

@@ -1320,7 +1320,9 @@ public:
if (auto host = wrapper.hostCallback)
{
if (host (wrapper.getVstEffectInterface(), hostOpcodeCanHostDo, 0, 0, const_cast<char*> ("sizeWindow"), 0) == (pointer_sized_int) 1)
auto status = host (wrapper.getVstEffectInterface(), hostOpcodeCanHostDo, 0, 0, const_cast<char*> ("sizeWindow"), 0);
if (status == (pointer_sized_int) 1 || getHostType().isAbletonLive())
{
isInSizeWindow = true;
sizeWasSuccessful = (host (wrapper.getVstEffectInterface(), hostOpcodeWindowSize, newWidth, newHeight, 0, 0) != 0);


+ 38
- 0
libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -115,6 +115,7 @@ class JuceVST3Component;
//==============================================================================
class JuceVST3EditController : public Vst::EditController,
public Vst::IMidiMapping,
public Vst::ChannelContext::IInfoListener,
public AudioProcessorListener
{
public:
@@ -147,6 +148,7 @@ public:
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IEditController2)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IMidiMapping)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::ChannelContext::IInfoListener)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IPluginBase, Vst::IEditController)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IDependent, Vst::IEditController)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IEditController)
@@ -429,6 +431,41 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramChangeParameter)
};
//==============================================================================
tresult PLUGIN_API setChannelContextInfos (Vst::IAttributeList* list) override
{
if (auto* instance = getPluginInstance())
{
if (list != nullptr)
{
AudioProcessor::TrackProperties trackProperties;
{
Vst::String128 channelName;
if (list->getString (Vst::ChannelContext::kChannelNameKey, channelName, sizeof (channelName)) == kResultTrue)
trackProperties.name = toString (channelName);
}
{
int64 colour;
if (list->getInt (Vst::ChannelContext::kChannelColorKey, colour) == kResultTrue)
trackProperties.colour = Colour (Vst::ChannelContext::GetRed ((uint32) colour), Vst::ChannelContext::GetGreen ((uint32) colour),
Vst::ChannelContext::GetBlue ((uint32) colour), Vst::ChannelContext::GetAlpha ((uint32) colour));
}
if (MessageManager::getInstance()->isThisTheMessageThread())
instance->updateTrackProperties (trackProperties);
else
MessageManager::callAsync ([trackProperties, instance] ()
{ instance->updateTrackProperties (trackProperties); });
}
}
return kResultOk;
}
//==============================================================================
tresult PLUGIN_API setComponentState (IBStream* stream) override
{
@@ -1120,6 +1157,7 @@ public:
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IAudioProcessor)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IUnitInfo)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint)
TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::ChannelContext::IInfoListener)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IComponent)
if (doUIDsMatch (targetIID, JuceAudioProcessor::iid))


+ 11
- 7
libs/juce/source/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm View File

@@ -35,9 +35,14 @@
#pragma clang diagnostic ignored "-Wextra-semi"
#endif
#ifdef _MSC_VER
#pragma warning (push)
// #pragma warning (disable : 4127)
// From MacOS 10.13 and iOS 11 Apple has (sensibly!) stopped defining a whole
// set of functions with rather generic names. However, we still need a couple
// of them to compile the files below.
#ifndef verify
#define verify(assertion) __Verify(assertion)
#endif
#ifndef verify_noerr
#define verify_noerr(errorCode) __Verify_noErr(errorCode)
#endif
#include "AU/CoreAudioUtilityClasses/AUBase.cpp"
@@ -60,10 +65,9 @@
#include "AU/CoreAudioUtilityClasses/ComponentBase.cpp"
#include "AU/CoreAudioUtilityClasses/MusicDeviceBase.cpp"
#undef verify
#undef verify_noerr
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning (pop)
#endif

+ 20
- 7
libs/juce/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -1065,6 +1065,19 @@ public:
jassertfalse; // xxx not implemented!
}
//==============================================================================
void updateTrackProperties (const TrackProperties& properties) override
{
if (properties.name.isNotEmpty())
{
CFStringRef contextName = properties.name.toCFString();
AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ContextName, kAudioUnitScope_Global,
0, &contextName, sizeof (CFStringRef));
CFRelease (contextName);
}
}
//==============================================================================
void getStateInformation (MemoryBlock& destData) override
{
@@ -1128,6 +1141,7 @@ public:
void refreshParameterList() override
{
parameters.clear();
paramIDToIndex.clear();
if (audioUnit != nullptr)
{
@@ -1158,6 +1172,7 @@ public:
ParamInfo* const param = new ParamInfo();
parameters.add (param);
param->paramID = ids[i];
paramIDToIndex[ids[i]] = i;
param->minValue = info.minValue;
param->maxValue = info.maxValue;
param->automatable = (info.flags & kAudioUnitParameterFlag_NonRealTime) == 0;
@@ -1250,6 +1265,7 @@ private:
};
OwnedArray<ParamInfo> parameters;
std::unordered_map<AudioUnitParameterID, int> paramIDToIndex;
MidiDataConcatenator midiConcatenator;
CriticalSection midiInLock;
@@ -1335,13 +1351,10 @@ private:
|| event.mEventType == kAudioUnitEvent_BeginParameterChangeGesture
|| event.mEventType == kAudioUnitEvent_EndParameterChangeGesture)
{
for (paramIndex = 0; paramIndex < parameters.size(); ++paramIndex)
{
const ParamInfo& p = *parameters.getUnchecked(paramIndex);
auto it = paramIDToIndex.find (event.mArgument.mParameter.mParameterID)
if (p.paramID == event.mArgument.mParameter.mParameterID)
break;
}
if (it != paramIDToIndex.end())
paramIndex = it->second;
if (! isPositiveAndBelow (paramIndex, parameters.size()))
return;
@@ -1351,7 +1364,7 @@ private:
{
case kAudioUnitEvent_ParameterValueChange:
{
const ParamInfo& p = *parameters.getUnchecked(paramIndex);
auto& p = *parameters.getUnchecked (paramIndex);
sendParamChangeMessageToListeners (paramIndex, (newValue - p.minValue) / (p.maxValue - p.minValue));
}
break;


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

@@ -68,6 +68,7 @@
#include <pluginterfaces/base/ipluginbase.h>
#include <pluginterfaces/base/ustring.h>
#include <pluginterfaces/gui/iplugview.h>
#include <pluginterfaces/gui/iplugviewcontentscalesupport.h>
#include <pluginterfaces/vst/ivstattributes.h>
#include <pluginterfaces/vst/ivstaudioprocessor.h>
#include <pluginterfaces/vst/ivstcomponent.h>
@@ -83,6 +84,7 @@
#include <pluginterfaces/vst/vsttypes.h>
#include <pluginterfaces/vst/ivstunits.h>
#include <pluginterfaces/vst/ivstmidicontrollers.h>
#include <pluginterfaces/vst/ivstchannelcontextinfo.h>
#include <public.sdk/source/common/memorystream.h>
#include <public.sdk/source/vst/vsteditcontroller.h>
#else
@@ -105,6 +107,7 @@
#include <pluginterfaces/gui/iplugview.h>
#include <pluginterfaces/gui/iplugviewcontentscalesupport.h>
#include <pluginterfaces/vst/ivstmidicontrollers.h>
#include <pluginterfaces/vst/ivstchannelcontextinfo.h>
#include <public.sdk/source/common/memorystream.cpp>
#include <public.sdk/source/common/pluginview.cpp>
#include <public.sdk/source/vst/vsteditcontroller.cpp>


+ 64
- 0
libs/juce/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -2101,6 +2101,67 @@ struct VST3PluginInstance : public AudioPluginInstance
return result;
}
//==============================================================================
void updateTrackProperties (const TrackProperties& properties) override
{
if (trackInfoListener != nullptr)
{
ComSmartPtr<Vst::IAttributeList> l (new TrackPropertiesAttributeList (properties));
trackInfoListener->setChannelContextInfos (l);
}
}
struct TrackPropertiesAttributeList : public Vst::IAttributeList
{
TrackPropertiesAttributeList (const TrackProperties& properties) : props (properties) {}
virtual ~TrackPropertiesAttributeList() {}
JUCE_DECLARE_VST3_COM_REF_METHODS
tresult PLUGIN_API queryInterface (const TUID queryIid, void** obj) override
{
TEST_FOR_AND_RETURN_IF_VALID (queryIid, Vst::IAttributeList)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (queryIid, FUnknown, Vst::IAttributeList)
*obj = nullptr;
return kNotImplemented;
}
tresult PLUGIN_API setInt (AttrID, Steinberg::int64) override { return kOutOfMemory; }
tresult PLUGIN_API setFloat (AttrID, double) override { return kOutOfMemory; }
tresult PLUGIN_API setString (AttrID, const Vst::TChar*) override { return kOutOfMemory; }
tresult PLUGIN_API setBinary (AttrID, const void*, Steinberg::uint32) override { return kOutOfMemory; }
tresult PLUGIN_API getFloat (AttrID, double&) override { return kResultFalse; }
tresult PLUGIN_API getBinary (AttrID, const void*&, Steinberg::uint32&) override { return kResultFalse; }
tresult PLUGIN_API getString (AttrID id, Vst::TChar* string, Steinberg::uint32 size) override
{
if (! std::strcmp (id, Vst::ChannelContext::kChannelNameKey))
{
Steinberg::String str (props.name.toRawUTF8());
str.copyTo (string, 0, (Steinberg::int32) jmin (size, (Steinberg::uint32) std::numeric_limits<Steinberg::int32>::max()));
return kResultTrue;
}
return kResultFalse;
}
tresult PLUGIN_API getInt (AttrID id, Steinberg::int64& value) override
{
if (! std::strcmp (Vst::ChannelContext::kChannelNameLengthKey, id)) value = props.name.length();
else if (! std::strcmp (Vst::ChannelContext::kChannelColorKey, id)) value = static_cast<Steinberg::int64> (props.colour.getARGB());
else return kResultFalse;
return kResultTrue;
}