diff --git a/pkgs/by-name/vo/voicevox-engine/make-installable.patch b/pkgs/by-name/vo/voicevox-engine/make-installable.patch new file mode 100644 index 000000000000..6cc3b04ad05b --- /dev/null +++ b/pkgs/by-name/vo/voicevox-engine/make-installable.patch @@ -0,0 +1,21 @@ +diff --git a/pyproject.toml b/pyproject.toml +index fa23446..6a7705c 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -40,7 +40,15 @@ use_parentheses = true + datas = "datas" # PyInstaller's argument + + [tool.poetry] +-package-mode = false ++name = "voicevox-engine" ++version = "@version@" ++authors = [] ++description = "" ++packages = [ { include = "voicevox_engine" } ] ++include = [ "resources/**/*", "run.py", "engine_manifest.json", "presets.yaml"] ++ ++[tool.poetry.scripts] ++voicevox-engine = "run:main" + + [tool.poetry.dependencies] + python = "~3.11" diff --git a/pkgs/by-name/vo/voicevox-engine/mecab-remove-deprecated.patch b/pkgs/by-name/vo/voicevox-engine/mecab-remove-deprecated.patch new file mode 100644 index 000000000000..b9ac0e1c1079 --- /dev/null +++ b/pkgs/by-name/vo/voicevox-engine/mecab-remove-deprecated.patch @@ -0,0 +1,92 @@ +diff --git a/lib/open_jtalk/src/mecab/src/char_property.h b/lib/open_jtalk/src/mecab/src/char_property.h +index 35f4b05..9c904ba 100644 +--- a/lib/open_jtalk/src/mecab/src/char_property.h ++++ b/lib/open_jtalk/src/mecab/src/char_property.h +@@ -37,7 +37,7 @@ class CharProperty { + inline const char *seekToOtherType(const char *begin, const char *end, + CharInfo c, CharInfo *fail, + size_t *mblen, size_t *clen) const { +- register const char *p = begin; ++ const char *p = begin; + *clen = 0; + while (p != end && c.isKindOf(*fail = getCharInfo(p, end, mblen))) { + p += *mblen; +diff --git a/lib/open_jtalk/src/mecab/src/darts.h b/lib/open_jtalk/src/mecab/src/darts.h +index 91b2eae..d6736cf 100644 +--- a/lib/open_jtalk/src/mecab/src/darts.h ++++ b/lib/open_jtalk/src/mecab/src/darts.h +@@ -404,10 +404,10 @@ class DoubleArrayImpl { + T result; + set_result(result, -1, 0); + +- register array_type_ b = array_[node_pos].base; +- register array_u_type_ p; ++ array_type_ b = array_[node_pos].base; ++ array_u_type_ p; + +- for (register size_t i = 0; i < len; ++i) { ++ for (size_t i = 0; i < len; ++i) { + p = b +(node_u_type_)(key[i]) + 1; + if (static_cast(b) == array_[p].check) + b = array_[p].base; +@@ -431,12 +431,12 @@ class DoubleArrayImpl { + size_t node_pos = 0) const { + if (!len) len = length_func_()(key); + +- register array_type_ b = array_[node_pos].base; +- register size_t num = 0; +- register array_type_ n; +- register array_u_type_ p; ++ array_type_ b = array_[node_pos].base; ++ size_t num = 0; ++ array_type_ n; ++ array_u_type_ p; + +- for (register size_t i = 0; i < len; ++i) { ++ for (size_t i = 0; i < len; ++i) { + p = b; // + 0; + n = array_[p].base; + if ((array_u_type_) b == array_[p].check && n < 0) { +@@ -469,8 +469,8 @@ class DoubleArrayImpl { + size_t len = 0) const { + if (!len) len = length_func_()(key); + +- register array_type_ b = array_[node_pos].base; +- register array_u_type_ p; ++ array_type_ b = array_[node_pos].base; ++ array_u_type_ p; + + for (; key_pos < len; ++key_pos) { + p = b +(node_u_type_)(key[key_pos]) + 1; +diff --git a/lib/open_jtalk/src/mecab/src/dictionary.cpp b/lib/open_jtalk/src/mecab/src/dictionary.cpp +index 5717d4d..3ab6e1f 100644 +--- a/lib/open_jtalk/src/mecab/src/dictionary.cpp ++++ b/lib/open_jtalk/src/mecab/src/dictionary.cpp +@@ -66,7 +66,7 @@ int progress_bar_darts(size_t current, size_t total) { + } + + template +-struct pair_1st_cmp: public std::binary_function { ++struct pair_1st_cmp { + bool operator()(const std::pair &x1, + const std::pair &x2) { + return x1.first < x2.first; +diff --git a/lib/open_jtalk/src/mecab/src/viterbi.cpp b/lib/open_jtalk/src/mecab/src/viterbi.cpp +index 6277fe9..5ccefb7 100644 +--- a/lib/open_jtalk/src/mecab/src/viterbi.cpp ++++ b/lib/open_jtalk/src/mecab/src/viterbi.cpp +@@ -318,11 +318,11 @@ template bool connect(size_t pos, Node *rnode, + const Connector *connector, + Allocator *allocator) { + for (;rnode; rnode = rnode->bnext) { +- register long best_cost = 2147483647; ++ long best_cost = 2147483647; + Node* best_node = 0; + for (Node *lnode = end_node_list[pos]; lnode; lnode = lnode->enext) { +- register int lcost = connector->cost(lnode, rnode); // local cost +- register long cost = lnode->cost + lcost; ++ int lcost = connector->cost(lnode, rnode); // local cost ++ long cost = lnode->cost + lcost; + + if (cost < best_cost) { + best_node = lnode; diff --git a/pkgs/by-name/vo/voicevox-engine/package.nix b/pkgs/by-name/vo/voicevox-engine/package.nix new file mode 100644 index 000000000000..bc9a67617e9f --- /dev/null +++ b/pkgs/by-name/vo/voicevox-engine/package.nix @@ -0,0 +1,126 @@ +{ + lib, + fetchFromGitHub, + python3Packages, + replaceVars, + voicevox-core, +}: + +python3Packages.buildPythonApplication rec { + pname = "voicevox-engine"; + version = "0.20.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "VOICEVOX"; + repo = "voicevox_engine"; + rev = "refs/tags/${version}"; + hash = "sha256-Gib5R7oleg+XXyu2V65EqrflQ1oiAR7a09a0MFhSITc="; + }; + + patches = [ + # the upstream package only uses poetry for dependency management, not for package definition + # this patch makes the package installable via poetry-core + (replaceVars ./make-installable.patch { + inherit version; + }) + ]; + + build-system = with python3Packages; [ + poetry-core + ]; + + dependencies = + [ + passthru.pyopenjtalk + ] + ++ (with python3Packages; [ + numpy + fastapi + jinja2 + python-multipart + uvicorn + soundfile + pyyaml + pyworld + semver + platformdirs + soxr + pydantic + starlette + ]); + + pythonRemoveDeps = [ + # upstream wants fastapi-slim, but we provide fastapi instead + "fastapi-slim" + ]; + + pythonRelaxDeps = true; + + preConfigure = '' + # copy demo metadata to temporary directory + mv resources/character_info test_character_info + + # populate the `character_info` directory with the actual model metadata instead of the demo metadata + cp -r --no-preserve=all ${passthru.resources}/character_info resources/character_info + + # the `character_info` directory copied from `resources` doesn't exactly have the expected format, + # so we transform them to be acceptable by `voicevox-engine` + pushd resources/character_info + for dir in *; do + # remove unused large files + rm $dir/*/*.png_large + + # rename directory from "$name_$uuid" to "$uuid" + mv $dir ''${dir#*"_"} + done + popd + ''; + + makeWrapperArgs = [ + ''--add-flags "--voicelib_dir=${voicevox-core}/lib"'' + ]; + + preCheck = '' + # some tests assume $HOME actually exists + export HOME=$(mktemp -d) + + # since the actual metadata files have been installed to `$out` by this point, + # we can move the demo metadata back to its place for the tests to succeed + rm -r resources/character_info + mv test_character_info resources/character_info + ''; + + disabledTests = [ + # this test checks the behaviour of openapi + # one of the functions returns a slightly different output due to openapi version differences + "test_OpenAPIの形が変わっていないことを確認" + ]; + + nativeCheckInputs = with python3Packages; [ + pytestCheckHook + syrupy + httpx + ]; + + passthru = { + resources = fetchFromGitHub { + owner = "VOICEVOX"; + repo = "voicevox_resource"; + rev = "refs/tags/${version}"; + hash = "sha256-m888DF9qgGbK30RSwNnAoT9D0tRJk6cD5QY72FRkatM="; + }; + + pyopenjtalk = python3Packages.callPackage ./pyopenjtalk.nix { }; + }; + + meta = { + changelog = "https://github.com/VOICEVOX/voicevox_engine/releases/tag/${version}"; + description = "Engine for the VOICEVOX speech synthesis software"; + homepage = "https://github.com/VOICEVOX/voicevox_engine"; + license = lib.licenses.lgpl3Only; + mainProgram = "voicevox-engine"; + maintainers = with lib.maintainers; [ tomasajt ]; + platforms = lib.platforms.linux ++ lib.platforms.darwin; + }; +} diff --git a/pkgs/by-name/vo/voicevox-engine/pyopenjtalk.nix b/pkgs/by-name/vo/voicevox-engine/pyopenjtalk.nix new file mode 100644 index 000000000000..01ef7ec6ee84 --- /dev/null +++ b/pkgs/by-name/vo/voicevox-engine/pyopenjtalk.nix @@ -0,0 +1,75 @@ +{ + lib, + python, + buildPythonPackage, + fetchFromGitHub, + fetchzip, + setuptools, + cython_0, + cmake, + numpy, + oldest-supported-numpy, + six, + tqdm, +}: + +let + dic-dirname = "open_jtalk_dic_utf_8-1.11"; + dic-src = fetchzip { + url = "https://github.com/r9y9/open_jtalk/releases/download/v1.11.1/${dic-dirname}.tar.gz"; + hash = "sha256-+6cHKujNEzmJbpN9Uan6kZKsPdwxRRzT3ZazDnCNi3s="; + }; +in +buildPythonPackage { + pname = "pyopenjtalk"; + version = "0-unstable-2023-09-08"; + pyproject = true; + + src = fetchFromGitHub { + owner = "VOICEVOX"; + repo = "pyopenjtalk"; + rev = "b35fc89fe42948a28e33aed886ea145a51113f88"; + hash = "sha256-DbZkCMdirI6wSRUQSJrkojyjGmViqGeQPO0kSKiw2gE="; + fetchSubmodules = true; + }; + + patches = [ + # this patch fixes the darwin build + # open_jtalk uses mecab, which uses the register keyword and std::binary_function, which are not allowed in c++17 + # this patch removes them + ./mecab-remove-deprecated.patch + ]; + + postPatch = '' + substituteInPlace pyproject.toml \ + --replace-fail 'setuptools