36#define JUCE_DECLARE_VST3_COM_REF_METHODS \
37 Steinberg::uint32 PLUGIN_API addRef() override { return (Steinberg::uint32) ++refCount; } \
38 Steinberg::uint32 PLUGIN_API release() override { const int r = --refCount; if (r == 0) delete this; return (Steinberg::uint32) r; }
40#define JUCE_DECLARE_VST3_COM_QUERY_METHODS \
41 Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID, void** obj) override \
45 return Steinberg::kNotImplemented; \
48inline bool doUIDsMatch (
const Steinberg::TUID a,
const Steinberg::TUID b)
noexcept
50 return std::memcmp (a, b,
sizeof (Steinberg::TUID)) == 0;
57class QueryInterfaceResult
60 QueryInterfaceResult() =
default;
62 QueryInterfaceResult (Steinberg::tresult resultIn,
void* ptrIn)
63 : result (resultIn), ptr (ptrIn) {}
65 bool isOk() const noexcept {
return result == Steinberg::kResultOk; }
67 Steinberg::tresult extract (
void** obj)
const
69 *obj = result == Steinberg::kResultOk ? ptr :
nullptr;
74 Steinberg::tresult result = Steinberg::kResultFalse;
87class InterfaceResultWithDeferredAddRef
90 InterfaceResultWithDeferredAddRef() =
default;
92 template <
typename Ptr>
93 InterfaceResultWithDeferredAddRef (Steinberg::tresult resultIn, Ptr* ptrIn)
94 : result (resultIn, ptrIn),
95 addRefFn (doAddRef<Ptr>) {}
97 bool isOk() const noexcept {
return result.isOk(); }
99 Steinberg::tresult extract (
void** obj)
const
101 const auto toReturn = result.extract (obj);
103 if (result.isOk() && *obj !=
nullptr)
104 NullCheckedInvocation::invoke (addRefFn, *obj);
110 template <
typename Ptr>
111 static void doAddRef (
void* obj) {
static_cast<Ptr*
> (obj)->addRef(); }
113 QueryInterfaceResult result;
114 void (*addRefFn) (
void*) =
nullptr;
117template <
typename ClassType>
struct UniqueBase {};
118template <
typename CommonClassType,
typename SourceClassType>
struct SharedBase {};
120template <
typename ToTest,
typename CommonClassType,
typename SourceClassType>
121InterfaceResultWithDeferredAddRef testFor (ToTest& toTest,
122 const Steinberg::TUID targetIID,
123 SharedBase<CommonClassType, SourceClassType>)
125 if (! doUIDsMatch (targetIID, CommonClassType::iid))
128 return { Steinberg::kResultOk,
static_cast<CommonClassType*
> (
static_cast<SourceClassType*
> (
std::addressof (toTest))) };
131template <
typename ToTest,
typename ClassType>
132InterfaceResultWithDeferredAddRef testFor (ToTest& toTest,
133 const Steinberg::TUID targetIID,
134 UniqueBase<ClassType>)
136 return testFor (toTest, targetIID, SharedBase<ClassType, ClassType>{});
139template <
typename ToTest>
140InterfaceResultWithDeferredAddRef testForMultiple (ToTest&,
const Steinberg::TUID) {
return {}; }
142template <
typename ToTest,
typename Head,
typename... Tail>
143InterfaceResultWithDeferredAddRef testForMultiple (ToTest& toTest,
const Steinberg::TUID targetIID, Head head, Tail... tail)
145 const auto result = testFor (toTest, targetIID, head);
150 return testForMultiple (toTest, targetIID, tail...);
154#if VST_VERSION < 0x030608
155 #define kAmbi1stOrderACN kBFormat
182#elif JUCE_LINUX || JUCE_BSD
189 bool isInput,
int busIndex)
193 if (processor !=
nullptr)
195 (Steinberg::
int32) busIndex, arrangement);
391 using X = AudioChannelSet;
398 const LayoutPair layoutTable[]
401 {
kMono, { X::centre } },
402 {
kStereo, { X::left, X::right } },
403 {
k30Cine, { X::left, X::right, X::centre } },
404 {
k30Music, { X::left, X::right, X::surround } },
405 {
k40Cine, { X::left, X::right, X::centre, X::surround } },
406 {
k50, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround } },
407 {
k51, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround } },
408 {
k60Cine, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::centreSurround } },
409 {
k61Cine, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::centreSurround } },
410 {
k60Music, { X::left, X::right, X::leftSurround, X::rightSurround, X::leftSurroundSide, X::rightSurroundSide } },
411 {
k61Music, { X::left, X::right, X::LFE, X::leftSurround, X::rightSurround, X::leftSurroundSide, X::rightSurroundSide } },
412 {
k70Music, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide } },
413 {
k70Cine, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre } },
414 {
k71Music, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide } },
415 {
k71Cine, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre } },
416 {
k40Music, { X::left, X::right, X::leftSurround, X::rightSurround } },
418 { k51_4, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
419 { k50_4, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
420 {
k71_2, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topSideLeft, X::topSideRight } },
421 {
k70_2, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topSideLeft, X::topSideRight } },
422 {
k71_4, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
423 {
k70_4, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
424 {
k71_6, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
425 {
k70_6, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
428 {
k91_4, { X::wideLeft, X::wideRight, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
429 {
k90_4, { X::wideLeft, X::wideRight, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
430 {
k91_6, { X::wideLeft, X::wideRight, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
431 {
k90_6, { X::wideLeft, X::wideRight, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
439inline bool isLayoutTableValid()
441 for (
const auto& item : detail::layoutTable)
447 for (
const auto& item : detail::layoutTable)
448 arrangements.insert (item.arrangement);
469 const auto arrangementMatches = [arr] (
const auto& layoutPair) {
return layoutPair.arrangement == arr; };
472 if (iter !=
std::end (detail::layoutTable))
473 return iter->channelOrder;
477 Array<AudioChannelSet::ChannelType> result;
478 result.ensureStorageAllocated (channels);
480 for (
auto i = 0; i < channels; ++i)
481 if (
const auto t = getChannelType (arr, getSpeaker (arr, i)))
484 if (getChannelCount (arr) == result.size())
495 AudioChannelSet channelSet;
498 inline static const Mapping mappings[]
505 Ambisonics() =
delete;
516 for (
const auto& mapping : Ambisonics::mappings)
517 if (channels == mapping.channelSet)
518 return mapping.arrangement;
520 const auto channelSetMatches = [&channels] (
const auto& layoutPair)
526 if (iter !=
std::end (detail::layoutTable))
527 return iter->arrangement;
531 for (
const auto& type : channels.getChannelTypes())
532 if (const auto t = getSpeakerType (channels, type))
535 if (getChannelCount (result) == channels.size())
545 for (
const auto& mapping : Ambisonics::mappings)
546 if (arr == mapping.arrangement)
547 return mapping.channelSet;
549 if (
const auto order = getSpeakerOrder (arr))
564 ChannelMapping (
const AudioChannelSet& layout,
bool activeIn)
565 : indices (makeChannelIndices (layout)), active (activeIn) {}
567 explicit ChannelMapping (
const AudioChannelSet& layout)
568 : ChannelMapping (layout, true) {}
570 explicit ChannelMapping (
const AudioProcessor::Bus& bus)
571 : ChannelMapping (bus.getLastEnabledLayout(), bus.isEnabled()) {}
573 int getJuceChannelForVst3Channel (
int vst3Channel)
const {
return indices[(
size_t) vst3Channel]; }
575 size_t size()
const {
return indices.size(); }
577 void setActive (
bool x) { active = x; }
578 bool isActive()
const {
return active; }
589 static std::vector<int> makeChannelIndices (
const AudioChannelSet& juceArrangement)
591 const auto order = [&]
593 const auto fallback = juceArrangement.getChannelTypes();
594 const auto vst3Arrangement = getVst3SpeakerArrangement (juceArrangement);
596 if (! vst3Arrangement.has_value())
599 const auto reordered = getSpeakerOrder (*vst3Arrangement);
601 if (! reordered.has_value() || AudioChannelSet::channelSetWithChannels (*reordered) != juceArrangement)
609 for (
const auto& type : order)
610 result.push_back (juceArrangement.getChannelIndexForType (type));
619class DynamicChannelMapping
622 DynamicChannelMapping (
const AudioChannelSet& channelSet,
bool active)
623 : set (channelSet), map (channelSet, active) {}
625 explicit DynamicChannelMapping (
const AudioChannelSet& channelSet)
626 : DynamicChannelMapping (channelSet, true) {}
628 explicit DynamicChannelMapping (
const AudioProcessor::Bus& bus)
629 : DynamicChannelMapping (bus.getLastEnabledLayout(), bus.isEnabled()) {}
631 AudioChannelSet getAudioChannelSet()
const {
return set; }
632 int getJuceChannelForVst3Channel (
int vst3Channel)
const {
return map.getJuceChannelForVst3Channel (vst3Channel); }
633 size_t size()
const {
return map.size(); }
636 bool isHostActive()
const {
return hostActive; }
638 bool isClientActive()
const {
return map.isActive(); }
640 void setHostActive (
bool active) { hostActive = active; }
641 void setClientActive (
bool active) { map.setActive (active); }
646 bool hostActive =
false;
658 return std::accumulate (map.begin(), map.end(), 0, [] (
auto acc,
const auto& item)
660 return acc + (item.isClientActive() ? (int) item.size() : 0);
664 return jmax (countUsedChannelsInVector (inputMap), countUsedChannelsInVector (outputMap));
667template <
typename FloatType>
671 void setSize (
int numChannels,
int blockSize)
673 buffer.setSize (numChannels, blockSize);
676 void clear() { channelCounter = 0; }
678 auto* getNextChannelBuffer() {
return buffer.getWritePointer (channelCounter++); }
680 auto getArrayOfWritePointers() {
return buffer.getArrayOfWritePointers(); }
683 AudioBuffer<FloatType> buffer;
684 int channelCounter = 0;
687template <
typename FloatType>
692 return getAudioBusPointer (detail::Tag<FloatType>{}, buf) ==
nullptr && buf.numChannels > 0;
696enum class Direction { input, output };
698template <Direction direction,
typename FloatType,
typename Iterator>
704 auto mapIterator = map.
begin();
706 for (
auto it = first; it != last; ++it, ++mapIterator)
709 auto** busPtr = getAudioBusPointer (detail::Tag<FloatType>{}, bus);
710 const auto expectedJuceChannels = (
int) mapIterator->size();
711 const auto actualVstChannels = (
int) bus.numChannels;
712 const auto limit =
jmin (expectedJuceChannels, actualVstChannels);
713 const auto anyChannelIsNull =
std::any_of (busPtr, busPtr + limit, [] (
auto* ptr) {
return ptr ==
nullptr; });
714 constexpr auto isInput = direction == Direction::input;
716 const auto channelCountIsUsable = isInput ? expectedJuceChannels <= actualVstChannels
717 : actualVstChannels <= expectedJuceChannels;
720 if (mapIterator->isHostActive() && (anyChannelIsNull || ! channelCountIsUsable))
725 jassert (actualVstChannels == expectedJuceChannels);
730 return std::none_of (mapIterator, map.
end(), [] (
const auto& item) { return item.isHostActive(); });
744template <
typename FloatType>
745class ClientBufferMapperData
748 void prepare (
int numChannels,
int blockSize)
750 scratchBuffer.setSize (numChannels, blockSize);
751 channels.reserve ((
size_t) jmin (128, numChannels));
758 scratchBuffer.clear();
761 const auto usedChannels = countUsedClientChannels (inputMap, outputMap);
764 const auto vstInputs = countValidBuses<FloatType> (
data.inputs,
data.numInputs);
766 if (! validateLayouts<Direction::input, FloatType> (
data.inputs,
data.inputs + vstInputs, inputMap))
767 return getBlankBuffer (usedChannels, (
int)
data.numSamples);
769 setUpInputChannels (data, (
size_t) vstInputs, scratchBuffer, inputMap, channels);
770 setUpOutputChannels (scratchBuffer, outputMap, channels);
772 const auto channelPtr = channels.empty() ? scratchBuffer.getArrayOfWritePointers()
775 return { channelPtr, (
int) channels.size(), (
int)
data.numSamples };
781 ScratchBuffer<FloatType>& scratchBuffer,
785 for (
size_t busIndex = 0; busIndex < map.
size(); ++busIndex)
787 const auto& mapping = map[busIndex];
789 if (! mapping.isClientActive())
792 const auto originalSize = channels.
size();
794 for (
size_t channelIndex = 0; channelIndex < mapping.size(); ++channelIndex)
795 channels.
push_back (scratchBuffer.getNextChannelBuffer());
797 if (mapping.isHostActive() && busIndex < vstInputs)
799 auto& bus =
data.inputs[busIndex];
802 jassert (mapping.size() <=
static_cast<size_t> (bus.numChannels));
804 auto** busPtr = getAudioBusPointer (detail::Tag<FloatType>{}, bus);
806 for (
size_t channelIndex = 0; channelIndex < mapping.size(); ++channelIndex)
808 FloatVectorOperations::copy (channels[(
size_t) mapping.getJuceChannelForVst3Channel ((
int) channelIndex) + originalSize],
809 busPtr[channelIndex],
810 (
size_t)
data.numSamples);
815 for (
size_t channelIndex = 0; channelIndex < mapping.size(); ++channelIndex)
816 FloatVectorOperations::clear (channels[originalSize + channelIndex], (
size_t)
data.numSamples);
821 static void setUpOutputChannels (ScratchBuffer<FloatType>& scratchBuffer,
825 for (
size_t i = 0, initialBusIndex = 0; i < (
size_t) map.
size(); ++i)
827 const auto& mapping = map[i];
829 if (mapping.isClientActive())
831 for (
size_t j = 0; j < mapping.size(); ++j)
833 if (channels.
size() <= initialBusIndex + j)
834 channels.
push_back (scratchBuffer.getNextChannelBuffer());
837 initialBusIndex += mapping.size();
842 AudioBuffer<FloatType> getBlankBuffer (
int usedChannels,
int usedSamples)
848 for (
auto i = 0; i < usedChannels; ++i)
850 channels.
push_back (scratchBuffer.getNextChannelBuffer());
851 FloatVectorOperations::clear (channels.
back(), usedSamples);
854 return { channels.
data(), (
int) channels.
size(), usedSamples };
858 ScratchBuffer<FloatType> scratchBuffer;
877class ClientBufferMapper
880 void updateFromProcessor (
const AudioProcessor& processor)
888 for (
const auto& pair : { Pair { inputMap,
true }, Pair { outputMap,
false } })
890 if (pair.map.empty())
892 for (
auto i = 0; i < processor.getBusCount (pair.isInput); ++i)
893 pair.map.emplace_back (*processor.getBus (pair.isInput, i));
898 jassert ((
size_t) processor.getBusCount (pair.isInput) == pair.map.size());
900 for (
size_t i = 0; i < (
size_t) processor.getBusCount (pair.isInput); ++i)
904 DynamicChannelMapping replacement { *processor.getBus (pair.isInput, (
int) i) };
905 replacement.setHostActive (pair.map[i].isHostActive());
913 void prepare (
int blockSize)
915 const auto findNumChannelsWhenAllBusesEnabled = [] (
const auto& map)
919 return acc + (int) item.size();
923 const auto numChannels =
jmax (findNumChannelsWhenAllBusesEnabled (inputMap),
924 findNumChannelsWhenAllBusesEnabled (outputMap));
926 floatData .prepare (numChannels, blockSize);
927 doubleData.prepare (numChannels, blockSize);
930 void updateActiveClientBuses (
const AudioProcessor::BusesLayout& clientBuses)
932 if ( (
size_t) clientBuses.inputBuses .size() != inputMap .
size()
933 || (
size_t) clientBuses.outputBuses.size() != outputMap.
size())
939 const auto sync = [] (
auto& map,
auto& client)
941 for (
size_t i = 0; i < map.
size(); ++i)
943 jassert (client[(
int) i] == AudioChannelSet::disabled() || client[(
int) i] == map[i].getAudioChannelSet());
944 map[i].setClientActive (client[(
int) i] != AudioChannelSet::disabled());
948 sync (inputMap, clientBuses.inputBuses);
949 sync (outputMap, clientBuses.outputBuses);
952 void setInputBusHostActive (
size_t bus,
bool state) { setHostActive (inputMap, bus, state); }
953 void setOutputBusHostActive (
size_t bus,
bool state) { setHostActive (outputMap, bus, state); }
955 auto& getData (detail::Tag<float>) {
return floatData; }
956 auto& getData (detail::Tag<double>) {
return doubleData; }
958 AudioChannelSet getRequestedLayoutForInputBus (
size_t bus)
const
960 return getRequestedLayoutForBus (inputMap, bus);
963 AudioChannelSet getRequestedLayoutForOutputBus (
size_t bus)
const
965 return getRequestedLayoutForBus (outputMap, bus);
974 if (bus < map.
size())
975 map[bus].setHostActive (state);
980 if (bus < map.
size() && map[bus].isHostActive())
981 return map[bus].getAudioChannelSet();
983 return AudioChannelSet::disabled();
986 ClientBufferMapperData<float> floatData;
987 ClientBufferMapperData<double> doubleData;
998template <
typename FloatType>
999class ClientRemappedBuffer
1002 ClientRemappedBuffer (ClientBufferMapperData<FloatType>& mapperData,
1006 : buffer (mapperData.getMappedBuffer (hostData, *inputMapIn, *outputMapIn)),
1007 outputMap (outputMapIn),
1012 : ClientRemappedBuffer (mapperIn.getData (detail::Tag<FloatType>{}),
1013 &mapperIn.getInputMap(),
1014 &mapperIn.getOutputMap(),
1018 ~ClientRemappedBuffer()
1021 const auto vstOutputs = (
size_t) countValidBuses<FloatType> (
data.outputs,
data.numOutputs);
1023 if (validateLayouts<Direction::output, FloatType> (
data.outputs,
data.outputs + vstOutputs, *outputMap))
1024 copyToHostOutputBuses (vstOutputs);
1026 clearHostOutputBuses (vstOutputs);
1029 AudioBuffer<FloatType> buffer;
1032 void copyToHostOutputBuses (
size_t vstOutputs)
const
1034 for (
size_t i = 0, juceBusOffset = 0; i < outputMap->
size(); ++i)
1036 const auto& mapping = (*outputMap)[i];
1038 if (mapping.isHostActive() && i < vstOutputs)
1040 auto& bus =
data.outputs[i];
1043 jassert (
static_cast<size_t> (bus.numChannels) <= mapping.size());
1045 if (mapping.isClientActive())
1047 for (
size_t j = 0; j < static_cast<size_t> (bus.numChannels); ++j)
1049 auto* hostChannel = getAudioBusPointer (detail::Tag<FloatType>{}, bus)[j];
1050 const auto juceChannel = juceBusOffset + (
size_t) mapping.getJuceChannelForVst3Channel ((
int) j);
1051 FloatVectorOperations::copy (hostChannel, buffer.getReadPointer ((
int) juceChannel), (
size_t)
data.numSamples);
1056 for (
size_t j = 0; j < static_cast<size_t> (bus.numChannels); ++j)
1058 auto* hostChannel = getAudioBusPointer (detail::Tag<FloatType>{}, bus)[j];
1059 FloatVectorOperations::clear (hostChannel, (
size_t)
data.numSamples);
1064 if (mapping.isClientActive())
1065 juceBusOffset += mapping.size();
1069 void clearHostOutputBuses (
size_t vstOutputs)
const
1076 auto** busPtr = getAudioBusPointer (detail::Tag<FloatType>{}, bus);
1077 std::for_each (busPtr, busPtr + bus.numChannels, [
this] (
auto* ptr)
1080 FloatVectorOperations::clear (ptr, (int) data.numSamples);
1099class HostBufferMapper
1105 mappings = std::move (arrangements);
1107 floatBusMap .resize (mappings.size());
1108 doubleBusMap.resize (mappings.size());
1109 busBuffers .resize (mappings.size());
1113 template <
typename FloatType>
1116 int channelIndexOffset = 0;
1118 for (
size_t i = 0; i < mappings.size(); ++i)
1120 const auto& mapping = mappings[i];
1121 associateBufferTo (busBuffers[i], get (detail::Tag<FloatType>{})[i], source, mapping, channelIndexOffset);
1122 channelIndexOffset += mapping.isActive() ? (
int) mapping.size() : 0;
1125 return busBuffers.data();
1129 template <
typename FloatType>
1132 template <
typename FloatType>
1138 template <
typename FloatType>
1141 AudioBuffer<FloatType>& buffer,
1142 const ChannelMapping& busMap,
1143 int channelStartOffset)
const
1147 for (
size_t i = 0; i < busMap.size(); ++i)
1149 bus.push_back (busMap.isActive() ? buffer.getWritePointer (channelStartOffset + busMap.getJuceChannelForVst3Channel ((
int) i))
1153 assignRawPointer (vstBuffers, bus.data());
1154 vstBuffers.
numChannels = (Steinberg::int32) busMap.size();
1158 auto&
get (detail::Tag<float>) {
return floatBusMap; }
1159 auto&
get (detail::Tag<double>) {
return doubleBusMap; }
1161 BusMap<float> floatBusMap;
1162 BusMap<double> doubleBusMap;
1171template <
class ObjectType>
1175 VSTComSmartPtr() =
default;
1176 VSTComSmartPtr (
const VSTComSmartPtr& other) noexcept : source (other.source) {
if (source !=
nullptr) source->addRef(); }
1177 ~VSTComSmartPtr() {
if (source !=
nullptr) source->release(); }
1179 explicit operator bool() const noexcept {
return operator!= (
nullptr); }
1180 ObjectType*
get() const noexcept {
return source; }
1181 ObjectType&
operator*() const noexcept {
return *source; }
1182 ObjectType* operator->() const noexcept {
return source; }
1184 VSTComSmartPtr& operator= (
const VSTComSmartPtr& other)
1193 return operator= (VSTComSmartPtr{});
1196 bool operator== (
std::nullptr_t)
const noexcept {
return source ==
nullptr; }
1197 bool operator!= (
std::nullptr_t)
const noexcept {
return source !=
nullptr; }
1202 return o !=
nullptr && o->
queryInterface (ObjectType::iid, (
void**) &source) == Steinberg::kResultOk;
1209 return factory->
createInstance (uuid, ObjectType::iid, (
void**) &source) == Steinberg::kResultOk;
1213 static auto addOwner (ObjectType* t)
1215 return VSTComSmartPtr (t,
true);
1219 static auto becomeOwner (ObjectType* t)
1221 return VSTComSmartPtr (t,
false);
1225 explicit VSTComSmartPtr (ObjectType*
object,
bool autoAddRef) noexcept : source (
object) {
if (source !=
nullptr && autoAddRef) source->addRef(); }
1226 ObjectType* source =
nullptr;
1230template <
class ObjectType>
1231auto addVSTComSmartPtrOwner (ObjectType* t)
1233 return VSTComSmartPtr<ObjectType>::addOwner (t);
1237template <
class ObjectType>
1238auto becomeVSTComSmartPtrOwner (ObjectType* t)
1240 return VSTComSmartPtr<ObjectType>::becomeOwner (t);
1255class StoredMidiMapping
1260 for (
auto& channel : channels)
1266 for (
size_t channelIndex = 0; channelIndex < channels.
size(); ++channelIndex)
1267 storeControllers (mapping, channels[channelIndex], channelIndex);
1274 return channels[(
size_t) channel][(
size_t) controller];
1286 for (
size_t controllerIndex = 0; controllerIndex < channel.size(); ++controllerIndex)
1287 channel[controllerIndex] = getSingleMapping (mapping, channelIndex, controllerIndex);
1291 size_t channelIndex,
1292 size_t controllerIndex)
1296 (int16) channelIndex,
1300 return returnCode == Steinberg::kResultTrue ? result : Steinberg::Vst::kNoParamId;
1310 MidiEventList() =
default;
1311 virtual ~MidiEventList() =
default;
1313 JUCE_DECLARE_VST3_COM_REF_METHODS
1314 JUCE_DECLARE_VST3_COM_QUERY_METHODS
1319 events.clearQuick();
1324 return (Steinberg::int32) events.size();
1330 if (isPositiveAndBelow ((
int) index, events.size()))
1332 e = events.getReference ((
int) index);
1333 return Steinberg::kResultTrue;
1336 return Steinberg::kResultFalse;
1342 return Steinberg::kResultTrue;
1350 for (Steinberg::int32 i = 0; i < numEvents; ++i)
1354 if (eventList.
getEvent (i, e) != Steinberg::kResultOk)
1357 if (
const auto message = toMidiMessage (e))
1362 template <
typename Callback>
1364 MidiBuffer& midiBuffer,
1365 StoredMidiMapping& mapping,
1366 Callback&& callback)
1368 toEventList (result, midiBuffer, &mapping, callback);
1373 toEventList (result, midiBuffer,
nullptr, [] (
auto&&...) {});
1377 enum class EventConversionKind
1389 template <
typename Callback>
1390 static bool sendMappedParameter (
const MidiMessage& msg,
1391 StoredMidiMapping* midiMapping,
1392 Callback&& callback)
1394 if (midiMapping ==
nullptr)
1397 const auto controlEvent = toVst3ControlEvent (msg);
1399 if (! controlEvent.has_value())
1402 const auto controlParamID = midiMapping->getMapping (createSafeChannel (msg.getChannel()),
1403 controlEvent->controllerNumber);
1405 if (controlParamID != Steinberg::Vst::kNoParamId)
1406 callback (controlParamID, controlEvent->paramValue);
1411 template <
typename Callback>
1413 const MidiMessageMetadata metadata,
1414 StoredMidiMapping* midiMapping,
1415 Callback&& callback)
1417 const auto msg = metadata.getMessage();
1422 const auto kind = midiMapping !=
nullptr ? EventConversionKind::hostToPlugin
1423 : EventConversionKind::pluginToHost;
1425 auto maybeEvent = createVstEvent (msg, metadata.data, kind);
1427 if (! maybeEvent.hasValue())
1430 maybeEvent->busIndex = 0;
1431 maybeEvent->sampleOffset = metadata.samplePosition;
1438 template <
typename Callback>
1440 MidiBuffer& midiBuffer,
1441 StoredMidiMapping* midiMapping,
1442 Callback&& callback)
1444 enum { maxNumEvents = 2048 };
1447 for (
const auto metadata : midiBuffer)
1449 if (++numEvents > maxNumEvents)
1456 Array<Steinberg::Vst::Event, CriticalSection> events;
1457 Atomic<int> refCount;
1459 static Steinberg::int16 createSafeChannel (
int channel)
noexcept {
return (Steinberg::int16)
jlimit (0, 15, channel - 1); }
1460 static int createSafeChannel (Steinberg::int16 channel)
noexcept {
return (
int)
jlimit (1, 16, channel + 1); }
1462 static Steinberg::int16 createSafeNote (
int note)
noexcept {
return (Steinberg::int16)
jlimit (0, 127, note); }
1463 static int createSafeNote (Steinberg::int16 note)
noexcept {
return jlimit (0, 127, (
int) note); }
1465 static float normaliseMidiValue (
int value)
noexcept {
return jlimit (0.0f, 1.0f, (
float) value / 127.0f); }
1466 static int denormaliseToMidiValue (
float value)
noexcept {
return roundToInt (jlimit (0.0f, 127.0f, value * 127.0f)); }
1472 e.noteOn.channel = createSafeChannel (msg.getChannel());
1473 e.noteOn.pitch = createSafeNote (msg.getNoteNumber());
1474 e.noteOn.velocity = normaliseMidiValue (msg.getVelocity());
1475 e.noteOn.length = 0;
1476 e.noteOn.tuning = 0.0f;
1477 e.noteOn.noteId = -1;
1485 e.noteOff.channel = createSafeChannel (msg.getChannel());
1486 e.noteOff.pitch = createSafeNote (msg.getNoteNumber());
1487 e.noteOff.velocity = normaliseMidiValue (msg.getVelocity());
1488 e.noteOff.tuning = 0.0f;
1489 e.noteOff.noteId = -1;
1499 e.data.bytes =
data;
1500 e.data.size = (uint32) msg.getRawDataSize();
1505 static Steinberg::Vst::Event createLegacyMIDIEvent (
int channel,
int controlNumber,
int value,
int value2 = 0)
1509 e.midiCCOut.channel = Steinberg::int8 (createSafeChannel (channel));
1510 e.midiCCOut.controlNumber = uint8 (jlimit (0, 255, controlNumber));
1511 e.midiCCOut.value = Steinberg::int8 (createSafeNote (value));
1512 e.midiCCOut.value2 = Steinberg::int8 (createSafeNote (value2));
1520 e.polyPressure.channel = createSafeChannel (msg.getChannel());
1521 e.polyPressure.pitch = createSafeNote (msg.getNoteNumber());
1522 e.polyPressure.pressure = normaliseMidiValue (msg.getAfterTouchValue());
1523 e.polyPressure.noteId = -1;
1529 return createLegacyMIDIEvent (msg.getChannel(),
1531 msg.getChannelPressureValue());
1536 return createLegacyMIDIEvent (msg.getChannel(),
1537 msg.getControllerNumber(),
1538 msg.getControllerValue());
1543 return createLegacyMIDIEvent (msg.getChannel(),
1545 msg.getNoteNumber(),
1546 msg.getAfterTouchValue());
1551 return createLegacyMIDIEvent (msg.getChannel(),
1553 msg.getRawData()[1],
1554 msg.getRawData()[2]);
1559 return createLegacyMIDIEvent (msg.getChannel(),
1561 msg.getProgramChangeNumber());
1566 return createLegacyMIDIEvent (msg.getChannel(),
1568 msg.getQuarterFrameValue());
1571 static Optional<Steinberg::Vst::Event> createVstEvent (
const MidiMessage& msg,
1572 const uint8* midiEventData,
1573 EventConversionKind kind)
noexcept
1576 return createNoteOnEvent (msg);
1578 if (msg.isNoteOff())
1579 return createNoteOffEvent (msg);
1582 return createSysExEvent (msg, midiEventData);
1584 if (msg.isChannelPressure())
1585 return createChannelPressureEvent (msg);
1587 if (msg.isPitchWheel())
1588 return createPitchWheelEvent (msg);
1590 if (msg.isProgramChange())
1591 return createProgramChangeEvent (msg);
1593 if (msg.isController())
1594 return createControllerEvent (msg);
1596 if (msg.isQuarterFrame())
1597 return createCtrlQuarterFrameEvent (msg);
1599 if (msg.isAftertouch())
1603 case EventConversionKind::hostToPlugin:
1604 return createPolyPressureEvent (msg);
1606 case EventConversionKind::pluginToHost:
1607 return createCtrlPolyPressureEvent (msg);
1620 return MidiMessage::controllerEvent (createSafeChannel (int16 (e.
channel)),
1622 createSafeNote (int16 (e.
value)));
1627 return MidiMessage::channelPressureChange (createSafeChannel (int16 (e.
channel)),
1628 createSafeNote (int16 (e.
value)));
1631 return MidiMessage::pitchWheel (createSafeChannel (int16 (e.
channel)),
1635 return MidiMessage::programChange (createSafeChannel (int16 (e.
channel)),
1636 createSafeNote (int16 (e.
value)));
1639 return MidiMessage::quarterFrame (createSafeChannel (int16 (e.
channel)),
1640 createSafeNote (int16 (e.
value)));
1643 return MidiMessage::aftertouchChange (createSafeChannel (int16 (e.
channel)),
1644 createSafeNote (int16 (e.
value)),
1645 createSafeNote (int16 (e.
value2)));
1663 const auto header = e.
bytes[0];
1664 const auto footer = e.
bytes[e.
size - 1];
1666 if (header != 0xf0 || footer != 0xf7)
1673 return MidiMessage::createSysExMessage (e.
bytes + 1, (
int) e.
size - 2);
1681 return MidiMessage::noteOn (createSafeChannel (e.noteOn.channel),
1682 createSafeNote (e.noteOn.pitch),
1683 (Steinberg::uint8) denormaliseToMidiValue (e.noteOn.velocity));
1686 return MidiMessage::noteOff (createSafeChannel (e.noteOff.channel),
1687 createSafeNote (e.noteOff.pitch),
1688 (Steinberg::uint8) denormaliseToMidiValue (e.noteOff.velocity));
1691 return MidiMessage::aftertouchChange (createSafeChannel (e.polyPressure.channel),
1692 createSafeNote (e.polyPressure.pitch),
1693 (Steinberg::uint8) denormaliseToMidiValue (e.polyPressure.pressure));
1696 return toMidiMessage (e.data);
1699 return toMidiMessage (e.midiCCOut);
1717 struct Vst3MidiControlEvent
1725 if (msg.isController())
1728 if (msg.isPitchWheel())
1731 if (msg.isChannelPressure())
1752class CachedParamValues
1755 CachedParamValues() =
default;
1758 : paramIds (
std::
move (paramIdsIn)), floatCache (paramIds.
size()) {}
1760 size_t size() const noexcept {
return floatCache.size(); }
1764 void set (Steinberg::int32 index,
float value)
1766 floatCache.setValueAndBits ((
size_t) index, value, 1);
1769 float exchangeWithoutNotifying (Steinberg::int32 index,
float value)
1771 return floatCache.exchangeValue ((
size_t) index, value);
1774 float get (Steinberg::int32 index)
const noexcept {
return floatCache.get ((
size_t) index); }
1776 template <
typename Callback>
1777 void ifSet (Callback&& callback)
1779 floatCache.ifSet ([&] (
size_t index,
float value, uint32_t)
1781 callback ((Steinberg::int32) index, value);
1787 FlaggedFloatCache<1> floatCache;
1792class ComponentRestarter :
private AsyncUpdater
1797 virtual ~Listener() =
default;
1798 virtual void restartComponentOnMessageThread (int32 flags) = 0;
1801 explicit ComponentRestarter (Listener& listenerIn)
1802 : listener (listenerIn) {}
1804 ~ComponentRestarter() noexcept
override
1806 cancelPendingUpdate();
1809 void restart (int32 newFlags)
1814 flags.fetch_or (newFlags);
1816 if (MessageManager::getInstance()->isThisTheMessageThread())
1817 handleAsyncUpdate();
1819 triggerAsyncUpdate();
1823 void handleAsyncUpdate()
override
1825 listener.restartComponentOnMessageThread (flags.exchange (0));
The basic interface of all interfaces.
virtual tresult PLUGIN_API queryInterface(const TUID _iid, void **obj)=0
Query for a pointer to the specified interface.
Class factory that any plug-in defines for creating class instances: IPluginFactory.
virtual tresult PLUGIN_API createInstance(FIDString cid, FIDString _iid, void **obj)=0
Create a new class instance.
UTF-16 string with fixed buffer size.
UTF-16 string class without buffer management.
UString & fromAscii(const char *src, int32 srcSize=-1)
Copy from ASCII string (srcSize is in code unit (count of char16)).
UString & assign(const char16 *src, int32 srcSize=-1)
Copy from UTF-16 buffer (srcSize is in code unit (count of char16)).
Audio processing interface: Vst::IAudioProcessor.
virtual tresult PLUGIN_API getBusArrangement(BusDirection dir, int32 index, SpeakerArrangement &arr)=0
Gets the bus arrangement for a given direction (input/output) and index.
List of events to process: Vst::IEventList.
virtual tresult PLUGIN_API addEvent(Event &e)=0
Adds a new event.
virtual int32 PLUGIN_API getEventCount()=0
Returns the count of events.
virtual tresult PLUGIN_API getEvent(int32 index, Event &e)=0
Gets parameter by index.
MIDI Mapping interface: Vst::IMidiMapping.
virtual tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, CtrlNumber midiControllerNumber, ParamID &id)=0
Gets an (preferred) associated ParamID for a given Input Event Bus index, channel and MIDI Controller...
static AudioChannelSet JUCE_CALLTYPE mono()
Creates a one-channel mono set (centre).
ChannelType
Represents different audio channel types.
@ ambisonicACN54
Seventh-order ambisonic channel number 54.
@ wideRight
Wide Right channel.
@ topFrontRight
Top Front Right channel.
@ ambisonicACN2
First-order ambisonic channel number 2.
@ topFrontLeft
Top Front Left channel.
@ ambisonicACN25
Fifth-order ambisonic channel number 25.
@ ambisonicACN48
Sixth-order ambisonic channel number 48.
@ ambisonicACN28
Fifth-order ambisonic channel number 28.
@ ambisonicACN59
Seventh-order ambisonic channel number 59.
@ ambisonicACN13
Third-order ambisonic channel number 13.
@ ambisonicACN8
Second-order ambisonic channel number 8.
@ ambisonicACN4
Second-order ambisonic channel number 4.
@ leftSurround
Ls channel.
@ topRearLeft
Top Rear Left channel.
@ ambisonicACN15
Third-order ambisonic channel number 15.
@ ambisonicACN38
Sixth-order ambisonic channel number 38.
@ centreSurround
Cs/S channel.
@ topSideLeft
Lts (AAX), Tsl (VST), Ltm (AU) channel for Dolby Atmos.
@ ambisonicACN30
Fifth-order ambisonic channel number 30.
@ ambisonicACN61
Seventh-order ambisonic channel number 61.
@ unknown
Unknown channel type.
@ ambisonicACN50
Seventh-order ambisonic channel number 50.
@ proximityRight
Proximity Right (Pr)
@ ambisonicACN19
Fourth-order ambisonic channel number 19.
@ ambisonicACN18
Fourth-order ambisonic channel number 18.
@ bottomRearCentre
Bottom Rear Center (Brc)
@ ambisonicACN27
Fifth-order ambisonic channel number 27.
@ ambisonicACN46
Sixth-order ambisonic channel number 46.
@ ambisonicACN57
Seventh-order ambisonic channel number 57.
@ ambisonicACN49
Seventh-order ambisonic channel number 49.
@ ambisonicACN62
Seventh-order ambisonic channel number 62.
@ ambisonicACN53
Seventh-order ambisonic channel number 53.
@ ambisonicACN51
Seventh-order ambisonic channel number 51.
@ ambisonicACN40
Sixth-order ambisonic channel number 40.
@ ambisonicACN21
Fourth-order ambisonic channel number 21.
@ bottomRearRight
Bottom Rear Right (Brr)
@ ambisonicACN26
Fifth-order ambisonic channel number 26.
@ ambisonicACN22
Fourth-order ambisonic channel number 22.
@ ambisonicACN12
Third-order ambisonic channel number 12.
@ bottomRearLeft
Bottom Rear Left (Brl)
@ ambisonicACN24
Fourth-order ambisonic channel number 24.
@ topSideRight
Rts (AAX), Tsr (VST), Rtm (AU) channel for Dolby Atmos.
@ ambisonicACN36
Sixth-order ambisonic channel number 36.
@ ambisonicACN1
First-order ambisonic channel number 1.
@ ambisonicACN32
Fifth-order ambisonic channel number 32.
@ ambisonicACN52
Seventh-order ambisonic channel number 52.
@ ambisonicACN41
Sixth-order ambisonic channel number 41.
@ rightSurroundRear
Rsr (AAX), Rcs (VST), Rrs (AU) channel.
@ rightSurroundSide
Rss (AXX), Side right "Sr" (VST), Right Centre "Rc" (AU) channel.
@ ambisonicACN29
Fifth-order ambisonic channel number 29.
@ ambisonicACN3
First-order ambisonic channel number 3.
@ ambisonicACN31
Fifth-order ambisonic channel number 31.
@ bottomFrontRight
Bottom Front Right (Bfr)
@ ambisonicACN6
Second-order ambisonic channel number 6.
@ ambisonicACN45
Sixth-order ambisonic channel number 45.
@ wideLeft
Wide Left channel.
@ ambisonicACN43
Sixth-order ambisonic channel number 43.
@ ambisonicACN17
Fourth-order ambisonic channel number 17.
@ proximityLeft
Proximity Left (Pl)
@ ambisonicACN35
Fifth-order ambisonic channel number 35.
@ ambisonicACN37
Sixth-order ambisonic channel number 37.
@ rightSurround
Rs channel.
@ ambisonicACN20
Fourth-order ambisonic channel number 20.
@ ambisonicACN16
Fourth-order ambisonic channel number 16.
@ ambisonicACN44
Sixth-order ambisonic channel number 44.
@ ambisonicACN55
Seventh-order ambisonic channel number 55.
@ ambisonicACN0
Zero-th ambisonic channel number 0.
@ bottomFrontCentre
Bottom Front Centre (Bfc)
@ ambisonicACN10
Third-order ambisonic channel number 10.
@ topRearCentre
Top Rear Centre channel.
@ ambisonicACN14
Third-order ambisonic channel number 14.
@ ambisonicACN60
Seventh-order ambisonic channel number 60.
@ topMiddle
Top Middle channel.
@ topFrontCentre
Top Front Centre channel.
@ ambisonicACN34
Fifth-order ambisonic channel number 34.
@ topRearRight
Top Rear Right channel.
@ LFE2
Second LFE channel.
@ rightCentre
Rc (AAX/VST), Rc used as Rss in AU for most layouts.
@ leftCentre
Lc (AAX/VST), Lc used as Lss in AU for most layouts.
@ ambisonicACN58
Seventh-order ambisonic channel number 58.
@ bottomSideRight
Bottom Side Right (Bsr)
@ ambisonicACN39
Sixth-order ambisonic channel number 39.
@ ambisonicACN5
Second-order ambisonic channel number 5.
@ ambisonicACN23
Fourth-order ambisonic channel number 23.
@ ambisonicACN11
Third-order ambisonic channel number 11.
@ leftSurroundSide
Lss (AXX), Side Left "Sl" (VST), Left Centre "LC" (AU) channel.
@ ambisonicACN56
Seventh-order ambisonic channel number 56.
@ bottomSideLeft
Bottom Side Left (Bsl)
@ ambisonicACN7
Second-order ambisonic channel number 7.
@ ambisonicACN33
Fifth-order ambisonic channel number 33.
@ discreteChannel0
Non-typed individual channels are indexed upwards from this value.
@ ambisonicACN47
Sixth-order ambisonic channel number 47.
@ bottomFrontLeft
Bottom Front Left (Bfl)
@ ambisonicACN42
Sixth-order ambisonic channel number 42.
@ leftSurroundRear
Lsr (AAX), Lcs (VST), Rls (AU) channel.
@ ambisonicACN63
Seventh-order ambisonic channel number 63.
@ ambisonicACN9
Third-order ambisonic channel number 9.
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
Creates a channel set for a list of channel types.
Wraps a pointer to a null-terminated UTF-16 character string, and provides various methods to operate...
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
const Speaker kSpeakerACN21
Ambisonic ACN 21.
const Speaker kSpeakerPr
Proximity Right (Pr)
const Speaker kSpeakerCs
Center of Surround (Cs) - Back Center - Surround (S)
const Speaker kSpeakerLfe
Subbass (Lfe)
const Speaker kSpeakerTsl
Top Side Left (Tsl)
const Speaker kSpeakerACN24
Ambisonic ACN 24.
const Speaker kSpeakerACN0
Ambisonic ACN 0.
const Speaker kSpeakerR
Right (R)
const Speaker kSpeakerBfr
Bottom Front Right (Bfr)
const Speaker kSpeakerRcs
Right of Center Surround (Rcs) - Back Right Center.
const Speaker kSpeakerACN2
Ambisonic ACN 2.
const Speaker kSpeakerACN1
Ambisonic ACN 1.
const Speaker kSpeakerTrc
Top Rear/Back Center (Trc)
const Speaker kSpeakerACN18
Ambisonic ACN 18.
const Speaker kSpeakerACN20
Ambisonic ACN 20.
const Speaker kSpeakerACN14
Ambisonic ACN 14.
const Speaker kSpeakerRc
Right of Center (Rc) - Front Right Center.
const Speaker kSpeakerBrr
Bottom Rear Right (Brr)
const Speaker kSpeakerM
Mono (M)
const Speaker kSpeakerL
Speaker Definitions.
const Speaker kSpeakerACN8
Ambisonic ACN 8.
const Speaker kSpeakerSl
Side Left (Sl)
const Speaker kSpeakerLs
Left Surround (Ls)
const Speaker kSpeakerBrc
Bottom Rear Center (Brc)
const Speaker kSpeakerACN11
Ambisonic ACN 11.
const SpeakerArrangement kEmpty
Speaker Arrangement Definitions.
const Speaker kSpeakerACN13
Ambisonic ACN 13.
const Speaker kSpeakerTsr
Top Side Right (Tsr)
const Speaker kSpeakerACN4
Ambisonic ACN 4.
const Speaker kSpeakerSr
Side Right (Sr)
const Speaker kSpeakerACN23
Ambisonic ACN 23.
const Speaker kSpeakerLcs
Left of Center Surround (Lcs) - Back Left Center.
const Speaker kSpeakerBsl
Bottom Side Left (Bsl)
const Speaker kSpeakerACN5
Ambisonic ACN 5.
const Speaker kSpeakerTfr
Top Front Right (Tfr)
const Speaker kSpeakerTrl
Top Rear/Back Left (Trl)
const Speaker kSpeakerACN6
Ambisonic ACN 6.
const Speaker kSpeakerACN16
Ambisonic ACN 16.
const Speaker kSpeakerACN19
Ambisonic ACN 19.
const Speaker kSpeakerLfe2
Subbass 2 (Lfe2)
const Speaker kSpeakerACN17
Ambisonic ACN 17.
int32 getChannelCount(SpeakerArrangement arr)
Returns number of channels used in speaker arrangement.
const Speaker kSpeakerRs
Right Surround (Rs)
const Speaker kSpeakerC
Center (C)
const Speaker kSpeakerBrl
Bottom Rear Left (Brl)
const Speaker kSpeakerBfc
Bottom Front Center (Bfc)
const Speaker kSpeakerACN3
Ambisonic ACN 3.
const Speaker kSpeakerACN22
Ambisonic ACN 22.
const Speaker kSpeakerBsr
Bottom Side Right (Bsr)
const Speaker kSpeakerACN12
Ambisonic ACN 12.
const Speaker kSpeakerACN15
Ambisonic ACN 15.
const Speaker kSpeakerACN7
Ambisonic ACN 7.
const Speaker kSpeakerACN9
Ambisonic ACN 9.
const Speaker kSpeakerLc
Left of Center (Lc) - Front Left Center.
const Speaker kSpeakerTfc
Top Front Center (Tfc)
const Speaker kSpeakerTfl
Top Front Left (Tfl)
const Speaker kSpeakerTc
Top Center Over-head, Top Middle (Tc)
const Speaker kSpeakerBfl
Bottom Front Left (Bfl)
const Speaker kSpeakerTrr
Top Rear/Back Right (Trr)
const Speaker kSpeakerPl
Proximity Left (Pl)
const Speaker kSpeakerACN10
Ambisonic ACN 10.
const FIDString kPlatformTypeNSView
The parent parameter in IPlugView::attached() is a NSView pointer.
const FIDString kPlatformTypeX11EmbedWindowID
The parent parameter in IPlugView::attached() is a X11 Window supporting XEmbed.
const FIDString kPlatformTypeHWND
The parent parameter in IPlugView::attached() is a HWND handle.
#define JUCE_BEGIN_NO_SANITIZE(warnings)
Disable sanitizers for a range of functions.
auto & get(ProcessorChain< Processors... > &chain) noexcept
Non-member equivalent of ProcessorChain::get which avoids awkward member template syntax.
SMTG_CONSTEXPR const CString kMono
used for Mono only plug-in [optional]
SMTG_CONSTEXPR const CString kStereo
used for Stereo only plug-in [optional]
Speaker Arrangement Definitions (SpeakerArrangement)
const SpeakerArrangement k71_6
L R C Lfe Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr.
const SpeakerArrangement k51
L R C Lfe Ls Rs.
const SpeakerArrangement k70Cine
L R C Ls Rs Lc Rc.
const SpeakerArrangement k71Cine
L R C Lfe Ls Rs Lc Rc.
const SpeakerArrangement k91_4
L R C Lfe Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr.
const SpeakerArrangement k70Music
L R C Ls Rs Sl Sr.
const SpeakerArrangement k40Cine
L R C S.
const SpeakerArrangement k61Cine
L R C Lfe Ls Rs Cs.
const SpeakerArrangement k60Music
L R Ls Rs Sl Sr.
const SpeakerArrangement kAmbi7thOrderACN
Seventh-Order with Ambisonic Channel Number (ACN) ordering and SN3D normalization (64 channels)
const SpeakerArrangement kAmbi5thOrderACN
Fifth-Order with Ambisonic Channel Number (ACN) ordering and SN3D normalization (36 channels)
const SpeakerArrangement k70_2
L R C Ls Rs Sl Sr Tsl Tsr.
const SpeakerArrangement k90_6
L R C Lfe Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr Tsl Tsr.
const SpeakerArrangement kAmbi6thOrderACN
Sixth-Order with Ambisonic Channel Number (ACN) ordering and SN3D normalization (49 channels)
const SpeakerArrangement k71_4
L R C Lfe Ls Rs Sl Sr Tfl Tfr Trl Trr.
const SpeakerArrangement k40Music
L R Ls Rs.
const SpeakerArrangement k30Music
L R S.
const SpeakerArrangement k70_6
L R C Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr.
const SpeakerArrangement k71Music
L R C Lfe Ls Rs Sl Sr.
const SpeakerArrangement k60Cine
L R C Ls Rs Cs.
const SpeakerArrangement k90_4
L R C Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr.
const SpeakerArrangement k50
L R C Ls Rs.
const SpeakerArrangement k70_4
L R C Ls Rs Sl Sr Tfl Tfr Trl Trr.
const SpeakerArrangement k71_2
L R C Lfe Ls Rs Sl Sr Tsl Tsr.
const SpeakerArrangement k61Music
L R Lfe Ls Rs Sl Sr.
const SpeakerArrangement k30Cine
L R C.
const SpeakerArrangement k91_6
L R C Lfe Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr Tsl Tsr.
All VST specific interfaces are located in Vst namespace.
uint8 controlNumber
see enum ControllerNumbers [0, 255]
uint64 Speaker
Bit for one speaker.
int8 value
value of Controller [0, 127]
uint32 ParamID
parameter identifier
TChar String128[128]
128 character UTF-16 string
char16 TChar
UTF-16 character.
int8 value2
[0, 127] used for pitch bend (kPitchBend) and polyPressure (kCtrlPolyPressure)
double ParamValue
parameter value type
int16 CtrlNumber
MIDI controller number (see ControllerNumbers for allowed values)
int8 channel
channel index in event bus [0, 15]
uint64 SpeakerArrangement
Bitset of speakers.
@ kPitchBend
Pitch Bend Change.
@ kCtrlProgramChange
Program Change (use LegacyMIDICCOutEvent.value only)
@ kCountCtrlNumber
Count of Controller Number.
@ kCtrlPolyPressure
Polyphonic Key Pressure (use LegacyMIDICCOutEvent.value for pitch and LegacyMIDICCOutEvent....
@ kCtrlQuarterFrame
Quarter Frame ((use LegacyMIDICCOutEvent.value only)
@ kAfterTouch
After Touch (associated to Channel Pressure)
Legacy MIDI CC Out event specific data.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
const DirectoryEntry & operator*(const DirectoryEntry &e) noexcept
A convenience operator so that the expression *it++ works correctly when it is an instance of RangedD...
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
signed int int32
A platform-independent 32-bit signed integer type.
constexpr int countNumberOfBits(uint32 n) noexcept
Returns the number of bits in a 32-bit integer.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
constexpr int numElementsInArray(Type(&)[N]) noexcept
Handy function for getting the number of elements in a simple const C array.
std::u16string toString(NumberT value)
convert an number to an UTF-16 string
Processing buffers of an audio bus.
int32 numChannels
number of audio channels in bus
uint64 silenceFlags
Bitset of silence state per channel.
Data event specific data.
uint32 type
type of this data block (see DataTypes)
@ kMidiSysEx
for MIDI system exclusive message
const uint8 * bytes
pointer to the data block
uint32 size
size in bytes of the data block bytes
EventStructure representing a single Event of different types associated to a specific event (kEvent)...
int32 sampleOffset
sample frames related to the current block start sample position
@ kScaleEvent
is ScaleEvent
@ kNoteExpressionValueEvent
is NoteExpressionValueEvent
@ kPolyPressureEvent
is PolyPressureEvent
@ kNoteExpressionTextEvent
is NoteExpressionTextEvent
@ kNoteOffEvent
is NoteOffEvent
@ kChordEvent
is ChordEvent
@ kNoteOnEvent
is NoteOnEvent
@ kLegacyMIDICCOutEvent
is LegacyMIDICCOutEvent
uint16 type
a value from EventTypes
Any data needed in audio processing.