Skip to content

VST3: order category tokens by meaning, map analyzers to Fx|Analyzer - #508

Merged
defiantnerd merged 1 commit into
free-audio:nextfrom
defiantnerd:vst3-features
Aug 9, 2026
Merged

VST3: order category tokens by meaning, map analyzers to Fx|Analyzer#508
defiantnerd merged 1 commit into
free-audio:nextfrom
defiantnerd:vst3-features

Conversation

@defiantnerd

@defiantnerd defiantnerd commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

VST3: order category tokens by meaning, map analyzers to Fx|Analyzer

clapCategoriesToVST3() once built the VST3 category string in the order
the CLAP descriptor listed its features, and it collected every matching
row of the translation table. Both got lost in 9a729a0 (ref: drive-by
cleanups, #155): the table lookup became a find_if which only ever
applies the first matching row, and the order preserving deduplication
became std::sort + std::unique, which sorts the tokens alphabetically.

Alphabetical is wrong for VST3. Hosts read the first token to file the
plugin and the second one as its sub menu, so an ARA plugin advertised
itself as "Fx|OnlyARA|Reverb" and an external instrument as
"External|Instrument". It also discards the one thing the plugin author
did tell us, namely which sub category they consider the important one.

On top of that a combined attribute like "Instrument|Drum" was treated
as one opaque string and could neither be deduplicated nor ordered
against its own parts, so CLAP_PLUGIN_FEATURE_DRUM_MACHINE ended up as
"Drum|Instrument".

Every attribute is split into its tokens now, each token is kept once in
the order it was first encountered, all matching table rows contribute
again, and a stable sort only moves the two kinds of token that may not
sit in the sub menu slot: a main category (Fx, Instrument) to the front,
a trait rather than a category (OnlyARA, External, Mono, ...) to the end.
Everything in between stays in the order the CLAP features were listed,
so "audio-effect, reverb, chorus" yields "Fx|Reverb|Modulation" while
"audio-effect, chorus, reverb" yields "Fx|Modulation|Reverb" - both
collapsed to the latter before.

CLAP_PLUGIN_FEATURE_ANALYZER maps to kFxAnalyzer instead of kAnalyzer.
The latter is documented as "not selectable as insert plug-in", which
kept CLAP analyzers out of the effect lists of hosts honouring that.

Finally the length check for PClassInfo2::subCategories ignored the
separators it appends, left no room for the terminating zero, and the
trailing pop_back() cut the truncation marker off again - besides being
undefined behaviour when no feature matched at all. Separators are
prepended now and the budget is kSubCategoriesSize - 1, so truncation
drops the categories the author ranked last.

Fixes #409

@defiantnerd
defiantnerd requested a review from baconpaul August 8, 2026 19:49
clapCategoriesToVST3() once built the VST3 category string in the order
the CLAP descriptor listed its features, and it collected every matching
row of the translation table. Both got lost in 9a729a0 (ref: drive-by
cleanups, free-audio#155): the table lookup became a find_if which only ever
applies the first matching row, and the order preserving deduplication
became std::sort + std::unique, which sorts the tokens alphabetically.

Alphabetical is wrong for VST3. Hosts read the first token to file the
plugin and the second one as its sub menu, so an ARA plugin advertised
itself as "Fx|OnlyARA|Reverb" and an external instrument as
"External|Instrument". It also discards the one thing the plugin author
did tell us, namely which sub category they consider the important one.

On top of that a combined attribute like "Instrument|Drum" was treated
as one opaque string and could neither be deduplicated nor ordered
against its own parts, so CLAP_PLUGIN_FEATURE_DRUM_MACHINE ended up as
"Drum|Instrument".

Every attribute is split into its tokens now, each token is kept once in
the order it was first encountered, all matching table rows contribute
again, and a stable sort only moves the two kinds of token that may not
sit in the sub menu slot: a main category (Fx, Instrument) to the front,
a trait rather than a category (OnlyARA, External, Mono, ...) to the end.
Everything in between stays in the order the CLAP features were listed,
so "audio-effect, reverb, chorus" yields "Fx|Reverb|Modulation" while
"audio-effect, chorus, reverb" yields "Fx|Modulation|Reverb" - both
collapsed to the latter before.

CLAP_PLUGIN_FEATURE_ANALYZER maps to kFxAnalyzer instead of kAnalyzer.
The latter is documented as "not selectable as insert plug-in", which
kept CLAP analyzers out of the effect lists of hosts honouring that.

Finally the length check for PClassInfo2::subCategories ignored the
separators it appends, left no room for the terminating zero, and the
trailing pop_back() cut the truncation marker off again - besides being
undefined behaviour when no feature matched at all. Separators are
prepended now and the budget is kSubCategoriesSize - 1, so truncation
drops the categories the author ranked last.

Fixes free-audio#409
@baconpaul

Copy link
Copy Markdown
Collaborator

Looks great and the sort logic is clear

@defiantnerd
defiantnerd merged commit 960ed3c into free-audio:next Aug 9, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants