mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
VST3: Add support for new wide/Atmos speaker layouts
This commit is contained in:
parent
34e454e3f1
commit
a42a498f5e
4 changed files with 158 additions and 35 deletions
|
|
@ -214,7 +214,6 @@ HarfBuzz Typeface implementation. New support for automatic font fallback
|
|||
will be introduced in JUCE 8, and this will obviate much of the need for
|
||||
CustomTypeface.
|
||||
|
||||
>>>>>>> 94454123d6 (Typeface: Implement platform typefaces using Harfbuzz hb_font_t)
|
||||
|
||||
## Change
|
||||
|
||||
|
|
@ -428,6 +427,48 @@ the licensing situation and encourages the creation of more open source software
|
|||
without impacting personal use of the JUCE framework.
|
||||
|
||||
|
||||
# Version 7.0.12
|
||||
|
||||
## Change
|
||||
|
||||
The function AudioChannelSet::create9point0point4, along with variants for
|
||||
9.1.4, 9.0.6, and 9.1.6, used to correspond to VST3 layouts k90_4, k91_4,
|
||||
k90_6, and k91_6 respectively. These functions now correspond to k90_4_W,
|
||||
k91_4_W, k90_6_W, and k91_6_W respectively.
|
||||
|
||||
**Possible Issues**
|
||||
|
||||
VST3 plugins that used these AudioChannelSet layouts to specify initial bus
|
||||
layouts, or to validate layouts in isBusesLayoutSupported, will now behave
|
||||
differently.
|
||||
|
||||
For example, if the host wants to check whether the k90_4 layout is supported,
|
||||
previously isBusesLayoutSupported() would have received the layout created by
|
||||
create9point0point4(), but will now receive the layout created by
|
||||
create9point0point4ITU().
|
||||
|
||||
**Workaround**
|
||||
|
||||
If you already have special-case handling for specific surround layouts,
|
||||
e.g. to enable or disable them in isBusesLayoutSupported(), you may need to
|
||||
add cases to handle the new AudioChannelSet::create*ITU() layout variants.
|
||||
|
||||
**Rationale**
|
||||
|
||||
Previously, the VST3 SDK only contained ITU higher-order surround layouts, but
|
||||
the higher-order layouts specified in JUCE used Atmos speaker positions rather
|
||||
than ITU speaker positions. This meant that JUCE had to remap speaker layouts
|
||||
between Atmos/ITU formats when communicating with VST3 plugins. This was
|
||||
confusing, as it required that the meaning of some channels was changed during
|
||||
the conversion.
|
||||
|
||||
In newer versions of the VST3 SDK, new "wide" left and right speaker
|
||||
definitions are available, allowing both ITU and Atmos surround layouts to be
|
||||
represented. The change in JUCE surfaces this distinction to the user, allowing
|
||||
them to determine e.g. whether the host has requested an ITU or an Atmos
|
||||
layout, and to handle these cases separately if necessary.
|
||||
|
||||
|
||||
# Version 7.0.10
|
||||
|
||||
## Change
|
||||
|
|
|
|||
|
|
@ -268,33 +268,51 @@ public:
|
|||
*/
|
||||
static AudioChannelSet JUCE_CALLTYPE create7point1point6();
|
||||
|
||||
/** Creates a set for a 9.0.4 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
|
||||
/** Creates a set for a 9.0.4 Atmos surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
|
||||
|
||||
Is equivalent to: k90_4 (VST3), AAX_eStemFormat_9_0_4 (AAX).
|
||||
Is equivalent to: k90_4_W (VST3), AAX_eStemFormat_9_0_4 (AAX).
|
||||
|
||||
@see create9point0point4ITU()
|
||||
*/
|
||||
static AudioChannelSet JUCE_CALLTYPE create9point0point4();
|
||||
|
||||
/** Creates a set for a 9.1.4 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
|
||||
/** Creates a set for a 9.1.4 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
|
||||
|
||||
Is equivalent to: k91_4 (VST3), AAX_eStemFormat_9_1_4 (AAX).
|
||||
Is equivalent to: k91_4_W (VST3), AAX_eStemFormat_9_1_4 (AAX).
|
||||
|
||||
@see create9point1point4ITU()
|
||||
*/
|
||||
static AudioChannelSet JUCE_CALLTYPE create9point1point4();
|
||||
|
||||
/** Creates a set for a 9.0.6 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
|
||||
/** Creates a set for a 9.0.6 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
|
||||
|
||||
Is equivalent to: k90_6 (VST3), AAX_eStemFormat_9_0_6 (AAX).
|
||||
Is equivalent to: k90_6_W (VST3), AAX_eStemFormat_9_0_6 (AAX).
|
||||
|
||||
@see create9point0point6ITU()
|
||||
*/
|
||||
static AudioChannelSet JUCE_CALLTYPE create9point0point6();
|
||||
|
||||
/** Creates a set for a 9.1.6 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
|
||||
/** Creates a set for a 9.1.6 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
|
||||
|
||||
Note that the VST3 layout arranges the front speakers "L Lc C Rc R", but the JUCE layout
|
||||
uses the arrangement "wideLeft left centre right wideRight". To maintain the relative
|
||||
positions of the speakers, the channels will be remapped accordingly. This means that the
|
||||
VST3 host's "L" channel will be received on a JUCE plugin's "wideLeft" channel, the
|
||||
"Lc" channel will be received on a JUCE plugin's "left" channel, and so on.
|
||||
Older versions of the VST3 SDK only supported ITU versions of the 9.0.4, 9.1.4, 9.0.6, and
|
||||
9.1.6 layouts, which have the front-channel ordering "L Lc C Rc R".
|
||||
To maintain the correct relative channel ordering, JUCE would perform the following mapping:
|
||||
L -> wideLeft, Lc -> left, Rc -> right, R -> wideRight
|
||||
|
||||
Is equivalent to: k91_6 (VST3), kAudioChannelLayoutTag_Atmos_9_1_6 (CoreAudio).
|
||||
The version of the VST3 SDK bundled with JUCE now supports Atmos versions of the above
|
||||
layouts, which have the front-channel ordering "Lw L C R Rw". This order matches the
|
||||
JUCE ordering, so no remapping is required.
|
||||
|
||||
create9point0point4(), create9point1point4(), create9point0point6(), and
|
||||
create9point1point6() now correspond to the VST3 k90_4_W, k91_4_W, k90_6_W, and k91_6_W
|
||||
Atmos layouts respectively.
|
||||
|
||||
If you need to support the old ITU layouts, use create9point0point4ITU(),
|
||||
create9point1point4ITU(), create9point0point6ITU(), and create9point1point6ITU() instead.
|
||||
|
||||
Is equivalent to: k91_6_W (VST3), kAudioChannelLayoutTag_Atmos_9_1_6 (CoreAudio).
|
||||
|
||||
@see create9point1point6ITU()
|
||||
*/
|
||||
static AudioChannelSet JUCE_CALLTYPE create9point1point6();
|
||||
|
||||
|
|
|
|||
|
|
@ -269,6 +269,8 @@ static std::optional<Steinberg::Vst::Speaker> getSpeakerType (const AudioChannel
|
|||
case AudioChannelSet::bottomRearLeft: return Steinberg::Vst::kSpeakerBrl;
|
||||
case AudioChannelSet::bottomRearCentre: return Steinberg::Vst::kSpeakerBrc;
|
||||
case AudioChannelSet::bottomRearRight: return Steinberg::Vst::kSpeakerBrr;
|
||||
case AudioChannelSet::wideLeft: return Steinberg::Vst::kSpeakerLw;
|
||||
case AudioChannelSet::wideRight: return Steinberg::Vst::kSpeakerRw;
|
||||
|
||||
case AudioChannelSet::discreteChannel0: return Steinberg::Vst::kSpeakerM;
|
||||
|
||||
|
|
@ -311,8 +313,6 @@ static std::optional<Steinberg::Vst::Speaker> getSpeakerType (const AudioChannel
|
|||
case AudioChannelSet::ambisonicACN61:
|
||||
case AudioChannelSet::ambisonicACN62:
|
||||
case AudioChannelSet::ambisonicACN63:
|
||||
case AudioChannelSet::wideLeft:
|
||||
case AudioChannelSet::wideRight:
|
||||
case AudioChannelSet::unknown:
|
||||
break;
|
||||
}
|
||||
|
|
@ -383,6 +383,8 @@ static std::optional<AudioChannelSet::ChannelType> getChannelType (Steinberg::Vs
|
|||
case Steinberg::Vst::kSpeakerBrl: return AudioChannelSet::bottomRearLeft;
|
||||
case Steinberg::Vst::kSpeakerBrc: return AudioChannelSet::bottomRearCentre;
|
||||
case Steinberg::Vst::kSpeakerBrr: return AudioChannelSet::bottomRearRight;
|
||||
case Steinberg::Vst::kSpeakerLw: return AudioChannelSet::wideLeft;
|
||||
case Steinberg::Vst::kSpeakerRw: return AudioChannelSet::wideRight;
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
@ -433,11 +435,15 @@ namespace detail
|
|||
{ 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 } },
|
||||
{ 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 } },
|
||||
|
||||
// The VST3 layout uses 'left/right' and 'left-of-center/right-of-center', but the JUCE layout uses 'left/right' and 'wide-left/wide-right'.
|
||||
{ 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 } },
|
||||
{ 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 } },
|
||||
{ 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 } },
|
||||
{ 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 } },
|
||||
{ k90_4_W, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::wideLeft, X::wideRight } },
|
||||
{ k91_4_W, { 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::wideLeft, X::wideRight } },
|
||||
{ k90_6_W, { 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, X::wideLeft, X::wideRight } },
|
||||
{ k91_6_W, { 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, X::wideLeft, X::wideRight } },
|
||||
|
||||
{ k90_4, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
|
||||
{ k91_4, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } },
|
||||
{ k90_6, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
|
||||
{ k91_6, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } },
|
||||
};
|
||||
|
||||
#if JUCE_DEBUG
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ public:
|
|||
expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right
|
||||
}
|
||||
|
||||
beginTest ("ChannelMapping for a 9.1.6 bus remaps the channels appropriately");
|
||||
beginTest ("ChannelMapping for a k91_6 bus remaps the channels appropriately");
|
||||
{
|
||||
ChannelMapping map (AudioChannelSet::create9point1point6());
|
||||
ChannelMapping map (AudioChannelSet::create9point1point6ITU());
|
||||
expect (map.size() == 16);
|
||||
|
||||
// VST3 order is:
|
||||
|
|
@ -80,6 +80,64 @@ public:
|
|||
// Tsl
|
||||
// Tsr
|
||||
// JUCE order is:
|
||||
// left
|
||||
// right
|
||||
// centre
|
||||
// LFE
|
||||
// leftSurround
|
||||
// rightSurround
|
||||
// leftCentre
|
||||
// rightCentre
|
||||
// leftSurroundSide
|
||||
// rightSurroundSide
|
||||
// topFrontLeft
|
||||
// topRearRight
|
||||
// topRearLeft
|
||||
// topRearRight
|
||||
// topSideLeft
|
||||
// topSideRight
|
||||
|
||||
expect (map.getJuceChannelForVst3Channel (0) == 0); // L -> left
|
||||
expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right
|
||||
expect (map.getJuceChannelForVst3Channel (2) == 2); // C -> centre
|
||||
expect (map.getJuceChannelForVst3Channel (3) == 3); // Lfe -> LFE
|
||||
expect (map.getJuceChannelForVst3Channel (4) == 4); // Ls -> leftSurround
|
||||
expect (map.getJuceChannelForVst3Channel (5) == 5); // Rs -> rightSurround
|
||||
expect (map.getJuceChannelForVst3Channel (6) == 6); // Lc -> leftCentre
|
||||
expect (map.getJuceChannelForVst3Channel (7) == 7); // Rc -> rightCentre
|
||||
expect (map.getJuceChannelForVst3Channel (8) == 8); // Sl -> leftSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (9) == 9); // Sr -> rightSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (10) == 10); // Tfl -> topFrontLeft
|
||||
expect (map.getJuceChannelForVst3Channel (11) == 11); // Tfr -> topFrontRight
|
||||
expect (map.getJuceChannelForVst3Channel (12) == 12); // Trl -> topRearLeft
|
||||
expect (map.getJuceChannelForVst3Channel (13) == 13); // Trr -> topRearRight
|
||||
expect (map.getJuceChannelForVst3Channel (14) == 14); // Tsl -> topSideLeft
|
||||
expect (map.getJuceChannelForVst3Channel (15) == 15); // Tsr -> topSideRight
|
||||
}
|
||||
|
||||
beginTest ("ChannelMapping for a k91_6_W bus remaps the channels appropriately");
|
||||
{
|
||||
ChannelMapping map (AudioChannelSet::create9point1point6());
|
||||
expect (map.size() == 16);
|
||||
|
||||
// VST3 order is:
|
||||
// L
|
||||
// R
|
||||
// C
|
||||
// Lfe
|
||||
// Ls
|
||||
// Rs
|
||||
// Sl
|
||||
// Sr
|
||||
// Tfl
|
||||
// Tfr
|
||||
// Trl
|
||||
// Trr
|
||||
// Tsl
|
||||
// Tsr
|
||||
// Lw
|
||||
// Rw
|
||||
// JUCE order is:
|
||||
// Left
|
||||
// Right
|
||||
// Centre
|
||||
|
|
@ -97,22 +155,22 @@ public:
|
|||
// Top Side Left
|
||||
// Top Side Right
|
||||
|
||||
expect (map.getJuceChannelForVst3Channel (0) == 12); // L -> wideLeft
|
||||
expect (map.getJuceChannelForVst3Channel (1) == 13); // R -> wideRight
|
||||
expect (map.getJuceChannelForVst3Channel (0) == 0); // L -> left
|
||||
expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right
|
||||
expect (map.getJuceChannelForVst3Channel (2) == 2); // C -> centre
|
||||
expect (map.getJuceChannelForVst3Channel (3) == 3); // Lfe -> LFE
|
||||
expect (map.getJuceChannelForVst3Channel (4) == 10); // Ls -> leftSurroundRear
|
||||
expect (map.getJuceChannelForVst3Channel (5) == 11); // Rs -> rightSurroundRear
|
||||
expect (map.getJuceChannelForVst3Channel (6) == 0); // Lc -> left
|
||||
expect (map.getJuceChannelForVst3Channel (7) == 1); // Rc -> right
|
||||
expect (map.getJuceChannelForVst3Channel (8) == 4); // Sl -> leftSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (9) == 5); // Sl -> leftSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (10) == 6); // Tfl -> topFrontLeft
|
||||
expect (map.getJuceChannelForVst3Channel (11) == 7); // Tfr -> topFrontRight
|
||||
expect (map.getJuceChannelForVst3Channel (12) == 8); // Trl -> topRearLeft
|
||||
expect (map.getJuceChannelForVst3Channel (13) == 9); // Trr -> topRearRight
|
||||
expect (map.getJuceChannelForVst3Channel (14) == 14); // Tsl -> topSideLeft
|
||||
expect (map.getJuceChannelForVst3Channel (15) == 15); // Tsr -> topSideRight
|
||||
expect (map.getJuceChannelForVst3Channel (6) == 4); // Sl -> leftSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (7) == 5); // Sr -> rightSurroundSide
|
||||
expect (map.getJuceChannelForVst3Channel (8) == 6); // Tfl -> topFrontLeft
|
||||
expect (map.getJuceChannelForVst3Channel (9) == 7); // Tfr -> topFrontRight
|
||||
expect (map.getJuceChannelForVst3Channel (10) == 8); // Trl -> topRearLeft
|
||||
expect (map.getJuceChannelForVst3Channel (11) == 9); // Trr -> topRearRight
|
||||
expect (map.getJuceChannelForVst3Channel (12) == 14); // Tsl -> topSideLeft
|
||||
expect (map.getJuceChannelForVst3Channel (13) == 15); // Tsr -> topSideRight
|
||||
expect (map.getJuceChannelForVst3Channel (14) == 12); // Lw -> wideLeft
|
||||
expect (map.getJuceChannelForVst3Channel (15) == 13); // Lw -> wideRight
|
||||
}
|
||||
|
||||
const auto blockSize = 128;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue