diff --git a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp index f7b99e2560..e5b85fa57b 100644 --- a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp +++ b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp @@ -267,7 +267,7 @@ private: auto itemId = 1; auto selectedId = -1; - for (auto i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i) + for (auto i = 1; i <= AudioChannelSet::maxChannelsOfNamedLayout; ++i) { for (const auto& set : AudioChannelSet::channelSetsWithNumberOfChannels (i)) { diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 29061f2acd..9043a0d777 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -241,6 +241,15 @@ static std::optional getSpeakerType (const AudioChannel case AudioChannelSet::ambisonicACN13: return Steinberg::Vst::kSpeakerACN13; case AudioChannelSet::ambisonicACN14: return Steinberg::Vst::kSpeakerACN14; case AudioChannelSet::ambisonicACN15: return Steinberg::Vst::kSpeakerACN15; + case AudioChannelSet::ambisonicACN16: return Steinberg::Vst::kSpeakerACN16; + case AudioChannelSet::ambisonicACN17: return Steinberg::Vst::kSpeakerACN17; + case AudioChannelSet::ambisonicACN18: return Steinberg::Vst::kSpeakerACN18; + case AudioChannelSet::ambisonicACN19: return Steinberg::Vst::kSpeakerACN19; + case AudioChannelSet::ambisonicACN20: return Steinberg::Vst::kSpeakerACN20; + case AudioChannelSet::ambisonicACN21: return Steinberg::Vst::kSpeakerACN21; + case AudioChannelSet::ambisonicACN22: return Steinberg::Vst::kSpeakerACN22; + case AudioChannelSet::ambisonicACN23: return Steinberg::Vst::kSpeakerACN23; + case AudioChannelSet::ambisonicACN24: return Steinberg::Vst::kSpeakerACN24; case AudioChannelSet::topSideLeft: return Steinberg::Vst::kSpeakerTsl; case AudioChannelSet::topSideRight: return Steinberg::Vst::kSpeakerTsr; case AudioChannelSet::bottomFrontLeft: return Steinberg::Vst::kSpeakerBfl; @@ -254,15 +263,6 @@ static std::optional getSpeakerType (const AudioChannel case AudioChannelSet::discreteChannel0: return Steinberg::Vst::kSpeakerM; - case AudioChannelSet::ambisonicACN16: - case AudioChannelSet::ambisonicACN17: - case AudioChannelSet::ambisonicACN18: - case AudioChannelSet::ambisonicACN19: - case AudioChannelSet::ambisonicACN20: - case AudioChannelSet::ambisonicACN21: - case AudioChannelSet::ambisonicACN22: - case AudioChannelSet::ambisonicACN23: - case AudioChannelSet::ambisonicACN24: case AudioChannelSet::ambisonicACN25: case AudioChannelSet::ambisonicACN26: case AudioChannelSet::ambisonicACN27: @@ -351,6 +351,15 @@ static std::optional getChannelType (Steinberg::Vs case Steinberg::Vst::kSpeakerACN13: return AudioChannelSet::ambisonicACN13; case Steinberg::Vst::kSpeakerACN14: return AudioChannelSet::ambisonicACN14; case Steinberg::Vst::kSpeakerACN15: return AudioChannelSet::ambisonicACN15; + case Steinberg::Vst::kSpeakerACN16: return AudioChannelSet::ambisonicACN16; + case Steinberg::Vst::kSpeakerACN17: return AudioChannelSet::ambisonicACN17; + case Steinberg::Vst::kSpeakerACN18: return AudioChannelSet::ambisonicACN18; + case Steinberg::Vst::kSpeakerACN19: return AudioChannelSet::ambisonicACN19; + case Steinberg::Vst::kSpeakerACN20: return AudioChannelSet::ambisonicACN20; + case Steinberg::Vst::kSpeakerACN21: return AudioChannelSet::ambisonicACN21; + case Steinberg::Vst::kSpeakerACN22: return AudioChannelSet::ambisonicACN22; + case Steinberg::Vst::kSpeakerACN23: return AudioChannelSet::ambisonicACN23; + case Steinberg::Vst::kSpeakerACN24: return AudioChannelSet::ambisonicACN24; case Steinberg::Vst::kSpeakerTsl: return AudioChannelSet::topSideLeft; case Steinberg::Vst::kSpeakerTsr: return AudioChannelSet::topSideRight; case Steinberg::Vst::kSpeakerLcs: return AudioChannelSet::leftSurroundRear; @@ -504,6 +513,10 @@ static std::optional getVst3SpeakerArrangeme std::call_once (detail::layoutTableCheckedFlag, [] { jassert (isLayoutTableValid()); }); #endif + for (const auto& mapping : Ambisonics::mappings) + if (channels == mapping.channelSet) + return mapping.arrangement; + const auto channelSetMatches = [&channels] (const auto& layoutPair) { return AudioChannelSet::channelSetWithChannels (layoutPair.channelOrder) == channels; @@ -522,10 +535,6 @@ static std::optional getVst3SpeakerArrangeme if (getChannelCount (result) == channels.size()) return result; - for (const auto& mapping : Ambisonics::mappings) - if (channels == mapping.channelSet) - return mapping.arrangement; - return {}; } @@ -533,13 +542,13 @@ inline std::optional getChannelSetForSpeakerArrangement (Steinb { using namespace Steinberg::Vst::SpeakerArr; - if (const auto order = getSpeakerOrder (arr)) - return AudioChannelSet::channelSetWithChannels (*order); - for (const auto& mapping : Ambisonics::mappings) if (arr == mapping.arrangement) return mapping.channelSet; + if (const auto order = getSpeakerOrder (arr)) + return AudioChannelSet::channelSetWithChannels (*order); + // VST3 <-> JUCE layout conversion error: report this bug to the JUCE forum return {}; } diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp index 15b420501e..27c10a2d58 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp @@ -550,6 +550,23 @@ public: expect (clientBuffers[3].channelBuffers64[0] == nullptr); } } + + beginTest ("Speaker layout conversions"); + { + using namespace Steinberg::Vst::SpeakerArr; + + for (const auto& [channelSet, arr] : { std::tuple (AudioChannelSet::ambisonic (1), kAmbi1stOrderACN), + std::tuple (AudioChannelSet::ambisonic (2), kAmbi2cdOrderACN), + std::tuple (AudioChannelSet::ambisonic (3), kAmbi3rdOrderACN), + std::tuple (AudioChannelSet::ambisonic (4), kAmbi4thOrderACN), + std::tuple (AudioChannelSet::ambisonic (5), kAmbi5thOrderACN), + std::tuple (AudioChannelSet::ambisonic (6), kAmbi6thOrderACN), + std::tuple (AudioChannelSet::ambisonic (7), kAmbi7thOrderACN), }) + { + expect (getVst3SpeakerArrangement (channelSet) == arr); + expect (channelSet == getChannelSetForSpeakerArrangement (arr)); + } + } } private: