A linguistic layer for synthrt, which adds the linguist contribution category to the packages synthrt loads.
synthrt knows about singers and inferences. It does not know about linguist contributions, and it does not need to: a contribution category is registered rather than built in, so a library linked into the program can add a kind of its own. wolf is that library. A package declares linguist contributions the same way it declares anything else and refers to one through the same syntax.
Nothing here is a program. It is a library for an editor or a tool to embed, alongside synthrt.
A package listing a linguist in its desc.json:
{
"contributions": {
"linguist": [
{ "id": "mandarin", "path": "./linguists/mandarin.json" }
]
}
}Each entry is a path to a linguist manifest:
{
"name": "普通话",
"interface": "org.openvpi.wolf.linguist.WolfLinguist",
"level": 1,
"variant": "wolf",
"exports": {
"phonemes": [ "a", "o", "e", "i", "u", "v" ]
},
"configuration": {},
"imports": [
{ "role": "linguist/g2p", "ref": ":inference/g2p" },
{ "role": "linguist/s2p", "ref": ":inference/s2p" }
]
}The (interface, level, variant) triple selects a provider through synthrt's interpreter discovery. The provider interprets exports, configuration, import options, execution factories, validators, and extensions for that contract.
The split follows the one synthrt already uses. exports is what the linguist declares about itself. configuration contains provider-specific resources. Relative paths resolve against the declaration file's directory.
A linguist is referred to like any other contribute:
vendor/sample=1.0:linguist/mandarin # fully qualified
vendor/sample:linguist/mandarin # version resolved from dependencies
:linguist/mandarin # within the referring package
Implement wolf::LinguistProvider and expose it through a wolf::LinguistProviderPlugin. The provider owns all contract-specific behavior, including import options, execution factories, validators, and spec extensions:
class MyLinguistProviderPlugin : public wolf::LinguistProviderPlugin {
public:
srt::Expected<std::unique_ptr<srt::ContribInterpreter>>
create(std::string_view interfaceName, int level, std::string_view variant) override {
// Validate the requested contract and return its provider.
}
};
STDC_EXPORT_PLUGIN(MyLinguistProviderPlugin)The bundled implementation lives in src/plugins/linguistproviders/wolf. Its WolfLinguistProvider supports org.openvpi.wolf.linguist.WolfLinguist, Level 1, variant wolf. The wolf library registers the category and defines the provider abstraction, but it does not create Wolf Level 1 runtime objects itself.
auto spec = package->contribution("linguist", "mandarin")
->as<wolf::LinguistSpec>();A SynthUnit reads the list of registered categories once, when it is constructed. wolf registers linguist before main, so any unit built afterwards has it. A plugin could not do the same: plugins load lazily through a unit, so by the time one runs its static initializers, that unit has already built its categories. Contributing a category is something a linked library does.
CMake 3.19 or later.
Boost.Test is needed only to build the tests.
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat # or ./bootstrap-vcpkg.sh
vcpkg install --x-manifest-root=../scripts/vcpkg-manifest --x-install-root=./installedAdd --x-feature=tests to bring in Boost.Test.
synthrt is not a vcpkg dependency here. Build and install it separately, then point at that install:
cmake -B build -G Ninja \
-DCMAKE_PREFIX_PATH=<synthrt install dir> \
-DCMAKE_INSTALL_PREFIX=<dir> \
-DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_BUILD_TYPE=Release
cmake --build build --target all
cmake --build build --target installcmake_minimum_required(VERSION 3.16)
project(example)
find_package(wolf CONFIG REQUIRED)
add_executable(example main.cpp)
target_link_libraries(example wolf::wolf)Linking wolf is what registers the category, so an executable that only wants linguist contributions available still links it directly rather than relying on a transitive dependency being pulled in.