Skip to content

Commit 182ef63

Browse files
committed
first commit
0 parents  commit 182ef63

13 files changed

Lines changed: 428 additions & 0 deletions

File tree

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.venv*/
2+
3+
__pycache__/
4+
build/
5+
dist/
6+
python/wfloat.egg-info/
7+
python/wfloat/lib/*.so
8+
python/wfloat/lib/*.pyd
9+
python/wfloat/lib/*.dll
10+
python/wfloat/lib/*.dylib
11+
python/wfloat/lib/*.lib

.vscode/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"files.watcherExclude": {
3+
"**/.git/objects/**": true,
4+
"**/.git/subtree-cache/**": true,
5+
"**/node_modules/*/**": true,
6+
"**/.venv*/**": true,
7+
}
8+
}

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include README.md
2+
recursive-include _build_support *.py
3+
recursive-include python *.py

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# wfloat
2+
3+
Low-level Python bindings for Wfloat TTS built from the modified `sherpa-onnx`
4+
source in this monorepo.
5+
6+
This package intentionally exposes the native binding surface directly. Model
7+
download, filesystem cache management, and higher-level client APIs are out of
8+
scope for this package skeleton.
9+
10+
## Scope
11+
12+
- Native `OfflineTts` binding for Wfloat TTS
13+
- Low-level config objects
14+
- Text preparation helpers
15+
- Wave writing helpers
16+
17+
## Build Notes
18+
19+
This package builds against the sibling `sherpa-onnx` source tree in this repo.
20+
It is meant to produce platform-specific wheels that bundle the compiled native
21+
extension inside the `wfloat` package.
22+
23+
```bash
24+
python3.12 -m venv .venv
25+
source .venv/bin/activate
26+
python -m pip install --upgrade pip setuptools wheel build cmake ninja
27+
28+
# optional override: export WFLOAT_SHERPA_ONNX_SOURCE_DIR=/some/other/sherpa-onnx
29+
python -m build --wheel
30+
31+
# Install the built wheel into the same venv for testing:
32+
python -m pip install dist/*.whl
33+
```
34+

_build_support/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

_build_support/cmake_extension.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Derived from sherpa-onnx/cmake/cmake_extension.py and adapted for the
2+
# standalone wfloat Python package.
3+
4+
import os
5+
import platform
6+
import shlex
7+
import shutil
8+
import subprocess
9+
import sys
10+
from pathlib import Path
11+
12+
import setuptools
13+
from setuptools.command.build_ext import build_ext
14+
15+
16+
def is_windows() -> bool:
17+
return platform.system() == "Windows"
18+
19+
20+
try:
21+
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
22+
23+
class bdist_wheel(_bdist_wheel):
24+
def finalize_options(self):
25+
_bdist_wheel.finalize_options(self)
26+
self.root_is_pure = False
27+
28+
except ImportError:
29+
bdist_wheel = None
30+
31+
32+
def cmake_extension(name, *args, **kwargs) -> setuptools.Extension:
33+
kwargs["language"] = "c++"
34+
return setuptools.Extension(name, sources=[], *args, **kwargs)
35+
36+
37+
def _get_repo_root() -> Path:
38+
return Path(__file__).resolve().parents[3]
39+
40+
41+
def _get_sherpa_onnx_source_dir() -> Path:
42+
env_dir = os.environ.get("WFLOAT_SHERPA_ONNX_SOURCE_DIR")
43+
if env_dir:
44+
source_dir = Path(env_dir).expanduser().resolve()
45+
else:
46+
source_dir = (_get_repo_root() / "sherpa-onnx").resolve()
47+
48+
if not source_dir.is_dir():
49+
raise RuntimeError(
50+
f"Could not find sherpa-onnx source tree at {source_dir}. "
51+
"Set WFLOAT_SHERPA_ONNX_SOURCE_DIR to override."
52+
)
53+
54+
return source_dir
55+
56+
57+
def _run(cmd):
58+
print("Running:", " ".join(cmd))
59+
subprocess.run(cmd, check=True)
60+
61+
62+
class BuildExtension(build_ext):
63+
def build_extension(self, ext: setuptools.extension.Extension):
64+
del ext
65+
66+
build_temp = Path(self.build_temp).resolve()
67+
build_lib = Path(self.build_lib).resolve()
68+
install_dir = build_lib / "wfloat"
69+
source_dir = _get_sherpa_onnx_source_dir()
70+
71+
build_temp.mkdir(parents=True, exist_ok=True)
72+
build_lib.mkdir(parents=True, exist_ok=True)
73+
74+
user_cmake_args = shlex.split(os.environ.get("SHERPA_ONNX_CMAKE_ARGS", ""))
75+
default_cmake_args = [
76+
"-DCMAKE_BUILD_TYPE=Release",
77+
f"-DCMAKE_INSTALL_PREFIX={install_dir}",
78+
"-DBUILD_SHARED_LIBS=ON",
79+
"-DBUILD_PIPER_PHONMIZE_EXE=OFF",
80+
"-DBUILD_PIPER_PHONMIZE_TESTS=OFF",
81+
"-DBUILD_ESPEAK_NG_EXE=OFF",
82+
"-DBUILD_ESPEAK_NG_TESTS=OFF",
83+
"-DSHERPA_ONNX_ENABLE_C_API=OFF",
84+
"-DSHERPA_ONNX_BUILD_C_API_EXAMPLES=OFF",
85+
"-DSHERPA_ONNX_ENABLE_CHECK=OFF",
86+
"-DSHERPA_ONNX_ENABLE_PYTHON=ON",
87+
"-DSHERPA_ONNX_ENABLE_TTS=ON",
88+
"-DSHERPA_ONNX_ENABLE_BINARY=OFF",
89+
"-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF",
90+
]
91+
92+
if not any(arg.startswith("-DPYTHON_EXECUTABLE=") for arg in user_cmake_args):
93+
default_cmake_args.append(f"-DPYTHON_EXECUTABLE={sys.executable}")
94+
95+
configure_cmd = [
96+
"cmake",
97+
*default_cmake_args,
98+
*user_cmake_args,
99+
"-B",
100+
str(build_temp),
101+
"-S",
102+
str(source_dir),
103+
]
104+
105+
build_cmd = ["cmake", "--build", str(build_temp), "--target", "install"]
106+
if is_windows():
107+
build_cmd.extend(["--config", "Release"])
108+
109+
parallel_level = os.environ.get("CMAKE_BUILD_PARALLEL_LEVEL")
110+
if parallel_level:
111+
build_cmd.extend(["--parallel", parallel_level])
112+
else:
113+
build_cmd.extend(["--parallel", "4"])
114+
115+
_run(configure_cmd)
116+
_run(build_cmd)
117+
118+
# Keep only the runtime files that belong inside the Python package.
119+
for extra_dir in ("bin", "include", "share"):
120+
candidate = install_dir / extra_dir
121+
if candidate.is_dir():
122+
shutil.rmtree(candidate)
123+
124+
pkgconfig_dir = install_dir / "lib" / "pkgconfig"
125+
if pkgconfig_dir.is_dir():
126+
shutil.rmtree(pkgconfig_dir)

out.wav

24.5 KB
Binary file not shown.

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[build-system]
2+
requires = ["setuptools>=68", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+

python/wfloat/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from ._bindings import (
2+
GeneratedAudio,
3+
GenerationConfig,
4+
OfflineTts,
5+
OfflineTtsConfig,
6+
OfflineTtsModelConfig,
7+
OfflineTtsWfloatModelConfig,
8+
WfloatPreparedText,
9+
git_date,
10+
git_sha1,
11+
prepare_wfloat_text,
12+
version,
13+
write_wave,
14+
)
15+
16+
__all__ = [
17+
"GeneratedAudio",
18+
"GenerationConfig",
19+
"OfflineTts",
20+
"OfflineTtsConfig",
21+
"OfflineTtsModelConfig",
22+
"OfflineTtsWfloatModelConfig",
23+
"WfloatPreparedText",
24+
"git_date",
25+
"git_sha1",
26+
"prepare_wfloat_text",
27+
"version",
28+
"write_wave",
29+
]
30+

python/wfloat/_bindings.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
try:
2+
from wfloat.lib._sherpa_onnx import (
3+
GeneratedAudio,
4+
GenerationConfig,
5+
OfflineTts,
6+
OfflineTtsConfig,
7+
OfflineTtsModelConfig,
8+
OfflineTtsWfloatModelConfig,
9+
WfloatPreparedText,
10+
git_date,
11+
git_sha1,
12+
prepare_wfloat_text,
13+
version,
14+
write_wave,
15+
)
16+
except ImportError as exc:
17+
raise ImportError(
18+
"Failed to import the wfloat native extension. "
19+
"Build the package from this repo or install a wheel for your platform."
20+
) from exc
21+
22+
23+
__all__ = [
24+
"GeneratedAudio",
25+
"GenerationConfig",
26+
"OfflineTts",
27+
"OfflineTtsConfig",
28+
"OfflineTtsModelConfig",
29+
"OfflineTtsWfloatModelConfig",
30+
"WfloatPreparedText",
31+
"git_date",
32+
"git_sha1",
33+
"prepare_wfloat_text",
34+
"version",
35+
"write_wave",
36+
]
37+

0 commit comments

Comments
 (0)