libspeech 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. libspeech-0.3.0/.github/workflows/cmake.yml +143 -0
  2. {libspeech-0.2.0 → libspeech-0.3.0}/.gitmodules +0 -5
  3. {libspeech-0.2.0 → libspeech-0.3.0}/CMakeLists.txt +23 -5
  4. {libspeech-0.2.0 → libspeech-0.3.0}/CONTRIBUTING.md +52 -10
  5. {libspeech-0.2.0 → libspeech-0.3.0}/PKG-INFO +37 -8
  6. {libspeech-0.2.0 → libspeech-0.3.0}/README.md +36 -7
  7. {libspeech-0.2.0 → libspeech-0.3.0}/checklist.md +103 -15
  8. libspeech-0.3.0/cmake/FixLCovPaths.cmake +9 -0
  9. libspeech-0.3.0/cmake/GenerateIframe.cmake +23 -0
  10. libspeech-0.3.0/cmake/coverage_iframe.html.in +160 -0
  11. libspeech-0.3.0/docs/CMakeLists.txt +44 -0
  12. libspeech-0.3.0/docs/Doxyfile.in +32 -0
  13. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/facebook_denoiser.h +1 -2
  14. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/onnx_model.h +1 -0
  15. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/speechbrain_denoiser.h +2 -3
  16. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/version.h +1 -1
  17. {libspeech-0.2.0 → libspeech-0.3.0}/src/audio.cpp +48 -77
  18. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/README.md +12 -6
  19. libspeech-0.3.0/tests/CMakeLists.txt +340 -0
  20. libspeech-0.3.0/tests/coverage_dashboard.html.in +607 -0
  21. libspeech-0.3.0/tests/genhtml.css +241 -0
  22. {libspeech-0.2.0 → libspeech-0.3.0}/tests/models/CMakeLists.txt +8 -0
  23. libspeech-0.3.0/tests/python/CMakeLists.txt +117 -0
  24. libspeech-0.2.0/.github/workflows/cmake.yml +0 -52
  25. libspeech-0.2.0/src/bindings/python/libspeech/__main__.py +0 -33
  26. libspeech-0.2.0/src/bindings/python/libspeech/core.py +0 -15
  27. libspeech-0.2.0/tests/CMakeLists.txt +0 -61
  28. libspeech-0.2.0/tests/python/CMakeLists.txt +0 -50
  29. {libspeech-0.2.0 → libspeech-0.3.0}/.clang-format +0 -0
  30. {libspeech-0.2.0 → libspeech-0.3.0}/.github/workflows/orchestrator.yml +0 -0
  31. {libspeech-0.2.0 → libspeech-0.3.0}/.github/workflows/wheels.yml +0 -0
  32. {libspeech-0.2.0 → libspeech-0.3.0}/.gitignore +0 -0
  33. {libspeech-0.2.0 → libspeech-0.3.0}/LICENSE +0 -0
  34. {libspeech-0.2.0 → libspeech-0.3.0}/audioflux_issues.md +0 -0
  35. {libspeech-0.2.0 → libspeech-0.3.0}/benchmarks/CMakeLists.txt +0 -0
  36. {libspeech-0.2.0 → libspeech-0.3.0}/benchmarks/cpp/CMakeLists.txt +0 -0
  37. {libspeech-0.2.0 → libspeech-0.3.0}/benchmarks/cpp/bench_stft.cpp +0 -0
  38. {libspeech-0.2.0 → libspeech-0.3.0}/cmake/AudioFlux.cmake +0 -0
  39. {libspeech-0.2.0 → libspeech-0.3.0}/cmake/Conan.cmake +0 -0
  40. {libspeech-0.2.0 → libspeech-0.3.0}/cmake/DynamicVersion.cmake +0 -0
  41. {libspeech-0.2.0 → libspeech-0.3.0}/cmake/ONNXRuntime.cmake +0 -0
  42. {libspeech-0.2.0 → libspeech-0.3.0}/cmake/PyProject.cmake +0 -0
  43. {libspeech-0.2.0 → libspeech-0.3.0}/conanfile.txt +0 -0
  44. {libspeech-0.2.0 → libspeech-0.3.0}/conda.recipe/meta.yaml +0 -0
  45. {libspeech-0.2.0 → libspeech-0.3.0}/docs/logo/README.md +0 -0
  46. {libspeech-0.2.0 → libspeech-0.3.0}/docs/logo/libspeech-logo-pods.svg +0 -0
  47. {libspeech-0.2.0 → libspeech-0.3.0}/docs/logo/libspeech-logo.svg +0 -0
  48. {libspeech-0.2.0 → libspeech-0.3.0}/examples/common.h +0 -0
  49. {libspeech-0.2.0 → libspeech-0.3.0}/examples/denoiser_app/controler.h +0 -0
  50. {libspeech-0.2.0 → libspeech-0.3.0}/examples/denoiser_app/main.cpp +0 -0
  51. {libspeech-0.2.0 → libspeech-0.3.0}/examples/main.cpp +0 -0
  52. {libspeech-0.2.0 → libspeech-0.3.0}/examples/silero_app/main.cpp +0 -0
  53. {libspeech-0.2.0 → libspeech-0.3.0}/git-submodule.sh +0 -0
  54. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/audio.h +0 -0
  55. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/dct.h +0 -0
  56. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/fft.h +0 -0
  57. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/mfcc.h +0 -0
  58. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/resample.h +0 -0
  59. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/stft.h +0 -0
  60. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/dsp/window.h +0 -0
  61. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/export.h +0 -0
  62. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/base_model.h +0 -0
  63. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/denoiser.h +0 -0
  64. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/models/silero_vad.h +0 -0
  65. {libspeech-0.2.0 → libspeech-0.3.0}/include/libspeech/utils/utils.h +0 -0
  66. {libspeech-0.2.0 → libspeech-0.3.0}/pyproject.toml +0 -0
  67. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/about.cpp +0 -0
  68. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/bind_audio.cpp +0 -0
  69. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/bind_dsp.cpp +0 -0
  70. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/bind_io.cpp +0 -0
  71. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/bind_models.cpp +0 -0
  72. {libspeech-0.2.0 → libspeech-0.3.0}/src/bindings/python/libspeech/__init__.py +0 -0
  73. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/dct.cpp +0 -0
  74. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/fft.cpp +0 -0
  75. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/mfcc.cpp +0 -0
  76. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/resample.cpp +0 -0
  77. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/stft.cpp +0 -0
  78. {libspeech-0.2.0 → libspeech-0.3.0}/src/dsp/window.cpp +0 -0
  79. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/base_model.cpp +0 -0
  80. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/denoiser.cpp +0 -0
  81. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/facebook_denoiser.cpp +0 -0
  82. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/onnx_model.cpp +0 -0
  83. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/silero_vad.cpp +0 -0
  84. {libspeech-0.2.0 → libspeech-0.3.0}/src/models/speechbrain_denoiser.cpp +0 -0
  85. {libspeech-0.2.0 → libspeech-0.3.0}/src/speech_umbrella_placeholder.cpp +0 -0
  86. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/aixlog/LICENSE +0 -0
  87. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/aixlog/README.md +0 -0
  88. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/aixlog/include/aixlog.hpp +0 -0
  89. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/LICENSE.md +0 -0
  90. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/README.md +0 -0
  91. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/UPSTREAM_PATCHES.md +0 -0
  92. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/dsp/resample_algorithm.h +0 -0
  93. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/flux_base.h +0 -0
  94. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/stft_algorithm.h +0 -0
  95. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/util/flux_util.h +0 -0
  96. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/util/flux_wave.h +0 -0
  97. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/vector/flux_complex.h +0 -0
  98. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/include/vector/flux_vector.h +0 -0
  99. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/fft_algorithm.c +0 -0
  100. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/fft_algorithm.h +0 -0
  101. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/filterDesign_fir.c +0 -0
  102. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/filterDesign_fir.h +0 -0
  103. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/flux_window.c +0 -0
  104. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/flux_window.h +0 -0
  105. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/resample_algorithm.c +0 -0
  106. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/dsp/resample_algorithm.h +0 -0
  107. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/flux_base.h +0 -0
  108. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/stft_algorithm.c +0 -0
  109. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/stft_algorithm.h +0 -0
  110. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/util/flux_util.c +0 -0
  111. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/util/flux_util.h +0 -0
  112. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/util/flux_wave.c +0 -0
  113. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/util/flux_wave.h +0 -0
  114. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_complex.c +0 -0
  115. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_complex.h +0 -0
  116. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_vector.c +0 -0
  117. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_vector.h +0 -0
  118. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_vectorOp.c +0 -0
  119. {libspeech-0.2.0 → libspeech-0.3.0}/src/third_party/audioflux/src/vector/flux_vectorOp.h +0 -0
  120. {libspeech-0.2.0 → libspeech-0.3.0}/src/utils/utils.cpp +0 -0
  121. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_dct.cpp +0 -0
  122. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_fft.cpp +0 -0
  123. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_mfcc.cpp +0 -0
  124. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_resample.cpp +0 -0
  125. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_stft.cpp +0 -0
  126. {libspeech-0.2.0 → libspeech-0.3.0}/tests/dsp/test_window.cpp +0 -0
  127. {libspeech-0.2.0 → libspeech-0.3.0}/tests/models/test_default_model_cache_dir.cpp +0 -0
  128. {libspeech-0.2.0 → libspeech-0.3.0}/tests/models/test_denoiser.cpp +0 -0
  129. {libspeech-0.2.0 → libspeech-0.3.0}/tests/python/test_audio.py +0 -0
  130. {libspeech-0.2.0 → libspeech-0.3.0}/tests/python/test_dsp.py +0 -0
  131. {libspeech-0.2.0 → libspeech-0.3.0}/tests/python/test_models.py +0 -0
  132. {libspeech-0.2.0 → libspeech-0.3.0}/tests/utest/utest.h +0 -0
  133. {libspeech-0.2.0 → libspeech-0.3.0}/tests/utest/utest_main.cxx +0 -0
  134. {libspeech-0.2.0 → libspeech-0.3.0}/version.py +0 -0
@@ -0,0 +1,143 @@
1
+ name: cmake stuff
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ workflow_call:
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ build-and-test:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest, windows-latest]
15
+
16
+ runs-on: ${{ matrix.os }}
17
+
18
+ steps:
19
+ - name: Checkout repository
20
+ uses: actions/checkout@v6
21
+ with:
22
+ submodules: true
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v6
26
+ with:
27
+ python-version: "3.11"
28
+ cache: "pip"
29
+
30
+ # speech::models (BUILD_MODELS=ON, the default) needs httpp on the
31
+ # CMAKE_PREFIX_PATH via find_package(httpp) -- see the "Model
32
+ # downloading" comment block in the top-level CMakeLists.txt. This has
33
+ # to happen before the configure step below, since CMake shells out to
34
+ # `python -c "import httpp; ..."` at configure time to locate it.
35
+ - name: Install httpp
36
+ run: pip install httpp
37
+
38
+ - name: Build Project
39
+ uses: threeal/cmake-action@v2.1.0
40
+ with:
41
+ build-dir: build
42
+ options: |
43
+ CMAKE_BUILD_TYPE=Release
44
+ BUILD_MODELS=ON
45
+ BUILD_TESTS=ON
46
+ BUILD_PYTHON=OFF
47
+
48
+ - name: Build
49
+ run: cmake --build build --config Release
50
+
51
+ - name: Run tests
52
+ run: ctest --test-dir build --output-on-failure --build-config Release
53
+
54
+ build-docs:
55
+ needs: build-and-test
56
+ runs-on: ubuntu-latest
57
+
58
+ steps:
59
+ - name: Checkout repository
60
+ uses: actions/checkout@v6
61
+
62
+ - name: Install Doxygen + graphviz
63
+ run: |
64
+ sudo apt-get update
65
+ sudo apt-get install -y doxygen graphviz
66
+
67
+ - name: Configure CMake
68
+ run: |
69
+ cmake -B build \
70
+ -DBUILD_MODELS=OFF \
71
+ -DBUILD_TESTS=OFF \
72
+ -DBUILD_DOCS=ON
73
+
74
+ - name: Build documentation
75
+ run: cmake --build build --target speech_docs
76
+
77
+ - name: Upload documentation artifact
78
+ uses: actions/upload-artifact@v7
79
+ with:
80
+ name: cmake-documentation
81
+ path: build/docs/out/html
82
+ retention-days: 5
83
+
84
+ build-coverage:
85
+ needs: build-and-test
86
+ runs-on: ubuntu-latest
87
+
88
+ steps:
89
+ - name: Checkout repository
90
+ uses: actions/checkout@v6
91
+ with:
92
+ submodules: true
93
+
94
+ - name: Set up Python
95
+ uses: actions/setup-python@v6
96
+ with:
97
+ python-version: "3.11"
98
+ cache: "pip"
99
+
100
+ # httpp: needed at CMake-configure time (see build-and-test above).
101
+ # coverage: drives speech_coverage_python. The rest of the Python side
102
+ # (nanobind, pytest, ...) is installed by CMakeLists.txt itself when
103
+ # BUILD_PYTHON=ON.
104
+ - name: Install python dependencies
105
+ run: pip install httpp coverage
106
+
107
+ - name: Install lcov
108
+ run: |
109
+ sudo apt-get update
110
+ sudo apt-get install -y lcov
111
+
112
+ # Same shape as ctoon's coverage job: every component (speech::dsp,
113
+ # speech::models C++ tests + the Python package's tests) is covered
114
+ # individually, then merged into coverage/total/ + a dashboard at
115
+ # coverage/index.html. BUILD_COVERAGE is an explicit opt-in (see the
116
+ # comment in tests/CMakeLists.txt for why it isn't implied by lcov
117
+ # merely being installed).
118
+ - name: Configure CMake with coverage
119
+ run: |
120
+ cmake -B build \
121
+ -DBUILD_MODELS=ON \
122
+ -DBUILD_TESTS=ON \
123
+ -DBUILD_PYTHON=ON \
124
+ -DBUILD_COVERAGE=ON
125
+
126
+ - name: Generate coverage report
127
+ run: cmake --build build --target speech_coverage
128
+
129
+ - name: Upload coverage to Codecov
130
+ uses: codecov/codecov-action@v5
131
+ with:
132
+ files: build/coverage/total/coverage.lcov
133
+ flags: unittests
134
+ name: codecov-libspeech
135
+ fail_ci_if_error: false
136
+ verbose: true
137
+
138
+ - name: Upload coverage artifact
139
+ uses: actions/upload-artifact@v7
140
+ with:
141
+ name: cmake-coverage-report
142
+ path: build/coverage/
143
+ retention-days: 5
@@ -3,8 +3,3 @@
3
3
  url = https://github.com/mackron/miniaudio.git
4
4
  shallow = true
5
5
 
6
- [submodule "src/third_party/dr_libs"]
7
- path = src/third_party/dr_libs
8
- url = https://github.com/mackron/dr_libs.git
9
- shallow = true
10
-
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.19)
3
3
  option(BUILD_PYTHON "export python module" off)
4
4
  option(BUILD_TESTS "build unit tests (speech::dsp only, no ONNXRuntime/httpp needed)" on)
5
5
  option(BUILD_MODELS "build speech::models + the speech library (needs ONNXRuntime download + the httpp package); off configures speech::dsp + tests only" on)
6
+ option(BUILD_DOCS "build the speech_docs Doxygen target (docs/)" off)
7
+ option(BUILD_COVERAGE "instrument speech_dsp with --coverage and enable the speech_coverage_cpp_dsp target (needs lcov/genhtml); OFF by default so a normal build isn't broken just because lcov happens to be installed" off)
6
8
 
7
9
  set(CMAKE_C_STANDARD 99 CACHE STRING "C version selection")
8
10
  set(CMAKE_C_STANDARD_REQUIRED ON)
@@ -108,8 +110,15 @@ if(BUILD_TESTS)
108
110
  add_subdirectory(tests)
109
111
  endif()
110
112
 
113
+ if(BUILD_DOCS)
114
+ add_subdirectory(docs)
115
+ endif()
116
+
111
117
  if(NOT BUILD_MODELS)
112
118
  message(STATUS "BUILD_MODELS=off: configuring speech::dsp + tests only, skipping ONNXRuntime/models/audio I/O.")
119
+ if(BUILD_TESTS)
120
+ speech_coverage_finalize()
121
+ endif()
113
122
  return()
114
123
  endif()
115
124
 
@@ -205,16 +214,18 @@ endif()
205
214
 
206
215
  # ---------------------------------------------------------------------------
207
216
  # speech::io -- audio file I/O (the Audio class: load/save/play/resample/
208
- # to_mono), backed by miniaudio + dr_libs. Mirrors speech::dsp/speech::models:
209
- # its own static library, its own namespace (speech::io in the C++ code,
210
- # matching this CMake alias).
217
+ # to_mono), backed by miniaudio alone (its ma_decoder/ma_encoder embed their
218
+ # own renamed copy of dr_wav/dr_mp3/dr_flac internally -- see the comment at
219
+ # the top of src/audio.cpp -- so the separate dr_libs submodule this used to
220
+ # also need is gone). Mirrors speech::dsp/speech::models: its own static
221
+ # library, its own namespace (speech::io in the C++ code, matching this
222
+ # CMake alias).
211
223
  # ---------------------------------------------------------------------------
212
224
  add_library(speech_io STATIC src/audio.cpp)
213
225
  add_library(speech::io ALIAS speech_io)
214
226
 
215
227
  target_include_directories(speech_io
216
228
  PUBLIC ${PROJECT_SOURCE_DIR}/include
217
- PRIVATE src/third_party/dr_libs
218
229
  PRIVATE src/third_party/aixlog/include
219
230
  )
220
231
  target_link_libraries(speech_io
@@ -481,7 +492,7 @@ if(DEFINED PYTHON_PROJECT_NAME)
481
492
  LIBRARY DESTINATION ${PYTHON_PROJECT_NAME}
482
493
  RUNTIME DESTINATION ${PYTHON_PROJECT_NAME})
483
494
 
484
- # The pure-Python files (__init__.py, __main__.py, core.py) need
495
+ # The pure-Python files (currently just __init__.py) need
485
496
  # their own explicit install rule -- scikit-build-core's automatic
486
497
  # Python-package discovery only looks for an immediate src/<name>
487
498
  # layout, so now that the package lives nested under
@@ -591,6 +602,13 @@ if(BUILD_TESTS AND DEFINED PYTHON_PROJECT_NAME AND NOT DEFINED SKBUILD)
591
602
  add_subdirectory(tests/python)
592
603
  endif()
593
604
 
605
+ # Merge every coverage component configured above into speech_coverage_total
606
+ # + the dashboard (no-op unless -DBUILD_COVERAGE=ON). The BUILD_MODELS=OFF
607
+ # early return above calls this too, since it never reaches this point.
608
+ if(BUILD_TESTS)
609
+ speech_coverage_finalize()
610
+ endif()
611
+
594
612
  if(DEFINED SKBUILD)
595
613
  RETURN()
596
614
  endif()
@@ -12,16 +12,15 @@ git clone https://github.com/MohammadRaziei/libspeech.git
12
12
  cd libspeech
13
13
 
14
14
  # Small, lightweight submodules:
15
- git submodule update --init src/third_party/miniaudio src/third_party/dr_libs src/third_party/indicators
15
+ git submodule update --init src/third_party/miniaudio
16
16
 
17
- # Mbed TLS (pinned to v3.6.2, kept shallow -- see .gitmodules) has its own
18
- # nested submodule ("framework") that also needs initializing:
19
- git submodule update --init src/third_party/mbedtls
20
- git submodule update --init --depth 1 src/third_party/mbedtls/framework
17
+ # speech::models (BUILD_MODELS=ON, the default) needs httpp on
18
+ # CMAKE_PREFIX_PATH for model downloads (HTTPS client + progress bar):
19
+ pip install httpp
21
20
  ```
22
21
 
23
- A few entries under `src/third_party/` (AudioFlux subset, aixlog, httplib)
24
- are **not** submodules -- those are copied directly into the repo, alongside
22
+ A few entries under `src/third_party/` (AudioFlux subset, aixlog) are
23
+ **not** submodules -- those are copied directly into the repo, alongside
25
24
  the actual submodules. See `src/third_party/README.md` for why and which
26
25
  ones.
27
26
 
@@ -103,9 +102,12 @@ what's already vendored under `src/third_party/`:
103
102
  what/why/before-after -- in `audioflux_issues.md` (or a new file
104
103
  following that structure for a different vendored project), so it can
105
104
  become an upstream PR later.
106
- 3. Security-critical code (crypto, TLS) is the exception: keep those as
107
- full git submodules (see Mbed TLS above), not cherry-picked/vendored,
108
- so security patches stay easy to pull in.
105
+ 3. Security/network-critical code is a different story: `httpp`
106
+ (HTTPS client + progress bar for model downloads) is a genuine,
107
+ separately-`pip install`able runtime dependency, not something to vendor
108
+ or patch in-tree -- see the `find_package(httpp)` comment block in
109
+ `CMakeLists.txt` for why (this replaced an earlier vendored
110
+ cpp-httplib + Mbed TLS setup for exactly this reason).
109
111
 
110
112
  ## Style notes
111
113
 
@@ -136,6 +138,46 @@ python version.py minor + # bump the minor version
136
138
  python version.py tag create patch # bump patch, commit, and tag a release
137
139
  ```
138
140
 
141
+ ## Docs and coverage
142
+
143
+ `-DBUILD_DOCS=ON` gives you `speech_docs` (Doxygen, warnings-free -- keep it
144
+ that way when you touch a public header). `-DBUILD_COVERAGE=ON` (needs
145
+ `lcov`; add `-DBUILD_PYTHON=ON` and `pip install coverage` for the Python
146
+ side) gives you `speech_coverage`, which runs every component's tests
147
+ instrumented, merges them, and writes a dashboard to
148
+ `build/coverage/index.html`. It mirrors ctoon's setup -- see the "Docs &
149
+ coverage" table in `README.md`. A new C++ module with its own test target
150
+ gets a coverage target by calling `speech_enable_coverage(<lib>)` and
151
+ `speech_add_cpp_coverage_target(...)` next to its tests (see
152
+ `tests/models/CMakeLists.txt` for a three-line example).
153
+
154
+ Two lcov 2.0 quirks worth knowing before you debug them yourself: its
155
+ `--list` output is wrong (use `--summary`, as the targets do), and an
156
+ `--extract`/`--exclude` pattern that matches nothing is a hard error unless
157
+ you pass `--ignore-errors unused`.
158
+
159
+ ## Packaging / CI changes
160
+
161
+ If you touch `CMakeLists.txt`'s install rules, `pyproject.toml`, or
162
+ `.github/workflows/wheels.yml`, actually build a wheel locally and inspect
163
+ its *contents* before opening a PR -- don't just read the config and
164
+ assume it's right:
165
+
166
+ ```bash
167
+ python -m build --wheel -o /tmp/wheelcheck
168
+ python -c "import zipfile; z = zipfile.ZipFile('/tmp/wheelcheck/<name>.whl'); [print(i.filename, i.file_size) for i in z.infolist()]"
169
+ ```
170
+
171
+ This project has twice shipped a packaging bug invisible from reading the
172
+ config alone -- a duplicated ~20MB ONNX Runtime binary (symlinks get
173
+ dereferenced both by `install(FILES ...)` and by the wheel-zip step), and a
174
+ wheel silently missing its intended `abi3` tag (`CIBW_ENVIRONMENT_CP312`
175
+ looked like a real cibuildwheel option by analogy with
176
+ `CIBW_ENVIRONMENT_LINUX`, but isn't -- cibuildwheel only recognizes
177
+ platform suffixes there, not Python-version ones, and silently no-ops
178
+ instead of erroring). Both only showed up by actually opening the built
179
+ artifact.
180
+
139
181
  ## Current project status
140
182
 
141
183
  See [`checklist.md`](checklist.md) for the up-to-date, detailed state of
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: libspeech
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Best library for speech
5
5
  Author-Email: Mohammad Raziei <mohammadraziei1375@gmail.com>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -43,7 +43,7 @@ Description-Content-Type: text/markdown
43
43
  [![Python Versions](https://img.shields.io/pypi/pyversions/libspeech)](https://pypi.org/project/libspeech/)
44
44
  [![C++ Standard](https://img.shields.io/badge/C++-17-blue)](https://en.cppreference.com/w/cpp/17)
45
45
 
46
- [![Build Status](https://github.com/mohammadraziei/libspeech/actions/workflows/build.yml/badge.svg)](https://github.com/mohammadraziei/libspeech/actions)
46
+ [![Build Status](https://github.com/mohammadraziei/libspeech/actions/workflows/cmake.yml/badge.svg)](https://github.com/mohammadraziei/libspeech/actions)
47
47
  [![Code Quality](https://sonarcloud.io/api/project_badges/measure?project=MohammadRaziei_libspeech&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=MohammadRaziei_libspeech)
48
48
  [![CodeFactor](https://www.codefactor.io/repository/github/mohammadraziei/libspeech/badge/master)](https://www.codefactor.io/repository/github/mohammadraziei/libspeech/overview/master)
49
49
  [![snyk.io](https://snyk.io/advisor/python/libspeech/badge.svg)](https://snyk.io/advisor/python/libspeech)
@@ -59,7 +59,7 @@ Description-Content-Type: text/markdown
59
59
  - 🔊 **Speech models** (`speech::models`): a `Denoiser` interface (Facebook/SpeechBrain backends) and Silero VAD
60
60
  - 🖥️ **Cross-platform**: Windows, Linux, macOS
61
61
  - 🐍 **Python bindings** (nanobind) mirroring the C++ API 1:1
62
- - 📦 **Zero system dependencies**: no `apt install libcurl-dev` / OpenSSL needed -- HTTPS model downloads go through a vendored [cpp-httplib](https://github.com/yhirose/cpp-httplib) + [Mbed TLS](https://github.com/Mbed-TLS/mbedtls) built from source
62
+ - 📦 **Zero system dependencies**: no `apt install libcurl-dev` / OpenSSL needed -- HTTPS model downloads go through [`httpp`](https://github.com/mohammadraziei/httpp) (`pip install httpp`), a separately-installed package with its own prebuilt HTTP(S) client and progress bar
63
63
 
64
64
  ## 📦 Installation
65
65
 
@@ -72,11 +72,12 @@ pip install libspeech
72
72
  ```bash
73
73
  git clone https://github.com/MohammadRaziei/libspeech.git
74
74
  cd libspeech
75
- git submodule update --init src/third_party/miniaudio src/third_party/dr_libs src/third_party/indicators
75
+ git submodule update --init src/third_party/miniaudio
76
76
 
77
- # Mbed TLS is pinned to v3.6.2 and kept as a shallow submodule (see .gitmodules):
78
- git submodule update --init src/third_party/mbedtls
79
- git submodule update --init --depth 1 src/third_party/mbedtls/framework
77
+ # speech::models (BUILD_MODELS=ON, the default) needs httpp on
78
+ # CMAKE_PREFIX_PATH for model downloads (HTTPS client + progress bar) --
79
+ # no more Mbed TLS/libcurl to build, just:
80
+ pip install httpp
80
81
 
81
82
  mkdir build && cd build
82
83
  cmake .. # downloads ONNX Runtime automatically on first configure
@@ -159,6 +160,34 @@ speech_test # everything
159
160
  Run everything with `cmake --build build --target speech_test`, or just
160
161
  `ctest` for the same suites without the extra build-tool chatter.
161
162
 
163
+ ### Docs & coverage
164
+
165
+ ```bash
166
+ cmake .. -DBUILD_DOCS=ON && cmake --build . --target speech_docs # Doxygen HTML -> build/docs/out/html
167
+ ```
168
+
169
+ Coverage follows the same layout as [ctoon](https://github.com/mohammadraziei/ctoon):
170
+ one target per component, a merged total, and a dashboard tying the reports
171
+ together.
172
+
173
+ ```bash
174
+ cmake .. -DBUILD_PYTHON=ON -DBUILD_COVERAGE=ON # + `pip install coverage`, lcov/genhtml on PATH
175
+ cmake --build . --target speech_coverage # everything below, then the merge + dashboard
176
+ ```
177
+
178
+ | Target | Covers | Output (under `build/coverage/`) |
179
+ |---|---|---|
180
+ | `speech_coverage_cpp_dsp` | `speech::dsp` (utest.h suite) | `cpp_dsp/` |
181
+ | `speech_coverage_cpp_models` | `speech::models` + download utils | `cpp_models/` |
182
+ | `speech_coverage_python` | the Python package's `.py` files (coverage.py) | `python/` |
183
+ | `speech_coverage_total` | lcov merge of all of the above | `total/` |
184
+
185
+ Open `build/coverage/index.html` for the dashboard. Each component (and the
186
+ total) also leaves a plain `coverage.lcov` next to its HTML, which is what CI
187
+ uploads to Codecov. `BUILD_COVERAGE` is off by default: it instruments
188
+ `speech_dsp`/`speech_models` with `--coverage`, which you don't want in a
189
+ normal build. Without `BUILD_PYTHON` you just get the C++ components.
190
+
162
191
  ## 🔧 Architecture
163
192
 
164
193
  libspeech is split into three independent C++ libraries (each with its own
@@ -168,7 +197,7 @@ library:
168
197
  | Namespace | CMake target | Python module | Depends on |
169
198
  |---|---|---|---|
170
199
  | `speech::dsp` | `speech_dsp` | `speech_dsp_py` | nothing but a vendored subset of [AudioFlux](https://github.com/libAudioFlux/audioflux)'s C sources |
171
- | `speech::io` | `speech_io` | `speech_io_py` | `speech::dsp` (for resampling), miniaudio, dr_libs |
200
+ | `speech::io` | `speech_io` | `speech_io_py` | `speech::dsp` (for resampling), miniaudio |
172
201
  | `speech::models` | `speech_models` | `speech_models_py` | ONNX Runtime, httplib+Mbed TLS (for downloading model weights) |
173
202
 
174
203
  See [`checklist.md`](checklist.md) for the detailed, up-to-date state of
@@ -17,7 +17,7 @@
17
17
  [![Python Versions](https://img.shields.io/pypi/pyversions/libspeech)](https://pypi.org/project/libspeech/)
18
18
  [![C++ Standard](https://img.shields.io/badge/C++-17-blue)](https://en.cppreference.com/w/cpp/17)
19
19
 
20
- [![Build Status](https://github.com/mohammadraziei/libspeech/actions/workflows/build.yml/badge.svg)](https://github.com/mohammadraziei/libspeech/actions)
20
+ [![Build Status](https://github.com/mohammadraziei/libspeech/actions/workflows/cmake.yml/badge.svg)](https://github.com/mohammadraziei/libspeech/actions)
21
21
  [![Code Quality](https://sonarcloud.io/api/project_badges/measure?project=MohammadRaziei_libspeech&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=MohammadRaziei_libspeech)
22
22
  [![CodeFactor](https://www.codefactor.io/repository/github/mohammadraziei/libspeech/badge/master)](https://www.codefactor.io/repository/github/mohammadraziei/libspeech/overview/master)
23
23
  [![snyk.io](https://snyk.io/advisor/python/libspeech/badge.svg)](https://snyk.io/advisor/python/libspeech)
@@ -33,7 +33,7 @@
33
33
  - 🔊 **Speech models** (`speech::models`): a `Denoiser` interface (Facebook/SpeechBrain backends) and Silero VAD
34
34
  - 🖥️ **Cross-platform**: Windows, Linux, macOS
35
35
  - 🐍 **Python bindings** (nanobind) mirroring the C++ API 1:1
36
- - 📦 **Zero system dependencies**: no `apt install libcurl-dev` / OpenSSL needed -- HTTPS model downloads go through a vendored [cpp-httplib](https://github.com/yhirose/cpp-httplib) + [Mbed TLS](https://github.com/Mbed-TLS/mbedtls) built from source
36
+ - 📦 **Zero system dependencies**: no `apt install libcurl-dev` / OpenSSL needed -- HTTPS model downloads go through [`httpp`](https://github.com/mohammadraziei/httpp) (`pip install httpp`), a separately-installed package with its own prebuilt HTTP(S) client and progress bar
37
37
 
38
38
  ## 📦 Installation
39
39
 
@@ -46,11 +46,12 @@ pip install libspeech
46
46
  ```bash
47
47
  git clone https://github.com/MohammadRaziei/libspeech.git
48
48
  cd libspeech
49
- git submodule update --init src/third_party/miniaudio src/third_party/dr_libs src/third_party/indicators
49
+ git submodule update --init src/third_party/miniaudio
50
50
 
51
- # Mbed TLS is pinned to v3.6.2 and kept as a shallow submodule (see .gitmodules):
52
- git submodule update --init src/third_party/mbedtls
53
- git submodule update --init --depth 1 src/third_party/mbedtls/framework
51
+ # speech::models (BUILD_MODELS=ON, the default) needs httpp on
52
+ # CMAKE_PREFIX_PATH for model downloads (HTTPS client + progress bar) --
53
+ # no more Mbed TLS/libcurl to build, just:
54
+ pip install httpp
54
55
 
55
56
  mkdir build && cd build
56
57
  cmake .. # downloads ONNX Runtime automatically on first configure
@@ -133,6 +134,34 @@ speech_test # everything
133
134
  Run everything with `cmake --build build --target speech_test`, or just
134
135
  `ctest` for the same suites without the extra build-tool chatter.
135
136
 
137
+ ### Docs & coverage
138
+
139
+ ```bash
140
+ cmake .. -DBUILD_DOCS=ON && cmake --build . --target speech_docs # Doxygen HTML -> build/docs/out/html
141
+ ```
142
+
143
+ Coverage follows the same layout as [ctoon](https://github.com/mohammadraziei/ctoon):
144
+ one target per component, a merged total, and a dashboard tying the reports
145
+ together.
146
+
147
+ ```bash
148
+ cmake .. -DBUILD_PYTHON=ON -DBUILD_COVERAGE=ON # + `pip install coverage`, lcov/genhtml on PATH
149
+ cmake --build . --target speech_coverage # everything below, then the merge + dashboard
150
+ ```
151
+
152
+ | Target | Covers | Output (under `build/coverage/`) |
153
+ |---|---|---|
154
+ | `speech_coverage_cpp_dsp` | `speech::dsp` (utest.h suite) | `cpp_dsp/` |
155
+ | `speech_coverage_cpp_models` | `speech::models` + download utils | `cpp_models/` |
156
+ | `speech_coverage_python` | the Python package's `.py` files (coverage.py) | `python/` |
157
+ | `speech_coverage_total` | lcov merge of all of the above | `total/` |
158
+
159
+ Open `build/coverage/index.html` for the dashboard. Each component (and the
160
+ total) also leaves a plain `coverage.lcov` next to its HTML, which is what CI
161
+ uploads to Codecov. `BUILD_COVERAGE` is off by default: it instruments
162
+ `speech_dsp`/`speech_models` with `--coverage`, which you don't want in a
163
+ normal build. Without `BUILD_PYTHON` you just get the C++ components.
164
+
136
165
  ## 🔧 Architecture
137
166
 
138
167
  libspeech is split into three independent C++ libraries (each with its own
@@ -142,7 +171,7 @@ library:
142
171
  | Namespace | CMake target | Python module | Depends on |
143
172
  |---|---|---|---|
144
173
  | `speech::dsp` | `speech_dsp` | `speech_dsp_py` | nothing but a vendored subset of [AudioFlux](https://github.com/libAudioFlux/audioflux)'s C sources |
145
- | `speech::io` | `speech_io` | `speech_io_py` | `speech::dsp` (for resampling), miniaudio, dr_libs |
174
+ | `speech::io` | `speech_io` | `speech_io_py` | `speech::dsp` (for resampling), miniaudio |
146
175
  | `speech::models` | `speech_models` | `speech_models_py` | ONNX Runtime, httplib+Mbed TLS (for downloading model weights) |
147
176
 
148
177
  See [`checklist.md`](checklist.md) for the detailed, up-to-date state of
@@ -20,7 +20,14 @@ its tests are green (see `AGENTS`/conversation ground rules).
20
20
  - [x] Establish logging convention: `aixlog`, `DEBUG` for lifecycle/results/errors, `TRACE` only where it exposes internal computation worth debugging (not on every call)
21
21
  - [x] Establish AudioFlux vendoring workflow: copy only the `.c`/`.h` files a ported operator needs into `src/third_party/audioflux/`, patch in place if needed, log every patch in `/audioflux_issues.md`
22
22
  - [x] Remove `src/third_party/audioflux` submodule entirely (nothing in the build references it anymore — everything comes from `src/third_party/audioflux`)
23
- - [ ] Decide fate of `src/third_party/indicators`, `dr_libs`, `miniaudio` (still used by `Audio`/CLI progress bars — keep for now, revisit)
23
+ - [x] Decide fate of `src/third_party/indicators`, `dr_libs`, `miniaudio`:
24
+ `indicators` fully removed — `src/audio.cpp`'s progress bar now uses
25
+ `httpp::progress::bar` (`<httpp/progress.hpp>`) from the `httpp` package
26
+ itself, same as the download-progress bar in
27
+ `speech::utils::downloadFile` (`.enable_progress()`). `dr_libs`/
28
+ `miniaudio` stay: they're audio file I/O (decode/encode/playback), an
29
+ unrelated concern from progress bars, still the only thing providing
30
+ that.
24
31
 
25
32
  > **Note for future DSP operators:** with the full AudioFlux submodule gone,
26
33
  > the next time we need to vendor a new `.c`/`.h` file (e.g. for STFT/MFCC),
@@ -117,18 +124,48 @@ its tests are green (see `AGENTS`/conversation ground rules).
117
124
  system dependencies, only source builds.
118
125
  - [ ] Verify full `speech` library CMake build end-to-end on a machine with normal internet access (this sandbox's own egress restrictions, now unrelated to CURL, are the only remaining blocker here)
119
126
  - [ ] `pip install` end-to-end smoke test (core promise of the project: zero system deps)
120
- - [ ] CI update: drop googletest/aixlog submodule steps, add utest.h-based test target
127
+ - [x] CI update: the googletest/aixlog-submodule cleanup itself turned out
128
+ to already be done (confirmed: no gtest/aixlog steps anywhere in
129
+ `.github/workflows/`, `.gitmodules` only lists `miniaudio`/`dr_libs`, and
130
+ `tests/CMakeLists.txt` already has a real `utest.h`-based `test_cpp_dsp`
131
+ target) -- this item was stale. What was actually still missing,
132
+ compared to `mohammadraziei/ctoon`'s CI structure: a `build-docs` job
133
+ (Doxygen) and a `build-coverage` job (lcov), both added to
134
+ `.github/workflows/cmake.yml` this session and verified by actually
135
+ building both locally first (see the Doxygen and Coverage entries
136
+ elsewhere in this file for what each surfaced). Deliberately not a full
137
+ copy of ctoon's job matrix -- no Rust/Go/Julia toolchain setup steps,
138
+ since libspeech doesn't have any of those bindings.
121
139
 
122
140
  ## Documentation
123
141
 
124
142
  - [x] `/audioflux_issues.md` — running log of every AudioFlux bug/quirk found + fixed, PR-ready
125
143
  - [x] `src/third_party/audioflux/README.md` — explains why vendored instead of submoduled
126
- - [ ] Update root `README.md` Quick Start to match actual current API (it currently references classes/methods that don't exist yet — `AudioProcessor`, `extract_features`, etc.)
127
- - [ ] `CONTRIBUTING.md` (referenced by README but missing)
128
- - [ ] Doxygen-style comments on public headers (`Audio`, `BaseModel`, ...)
129
-
130
- ## Python bindings (nanobind)
131
-
144
+ - [x] Update root `README.md` Quick Start to match actual current API —
145
+ the Quick Start itself was already fixed (real `Audio`/`MFCC`/`Denoiser`/
146
+ `SileroVad` API, not the old `AudioProcessor`/`extract_features`), but
147
+ the separate "From source" build steps and the "Zero system
148
+ dependencies" bullet were still stale (Mbed TLS/`indicators` submodule
149
+ init steps that no longer exist since the `httpp` migration) — fixed,
150
+ plus a broken CI badge link (`workflows/build.yml` doesn't exist;
151
+ pointed it at `workflows/cmake.yml`).
152
+ - [x] `CONTRIBUTING.md` (referenced by README) — was already written
153
+ earlier (see below), just stale by the time of this check (still
154
+ mentioned Mbed TLS's nested submodule and `src/third_party/indicators`,
155
+ both removed since); refreshed to match current reality.
156
+ - [x] Doxygen-style comments on public headers: the `speech_docs` target
157
+ (+ `build-docs` CI job) surfaced 13 concrete warnings, all now fixed and
158
+ verified -- `speech_docs` builds with **0** warnings. Real gaps closed:
159
+ missing/wrong `@param` docs on `FacebookDenoiser`/`SpeechBrainDenoiser`
160
+ constructors (documented `base_dir` for a parameter that doesn't exist,
161
+ omitted `sample_rate`), a stale `@param sample_rate` on both `process()`
162
+ methods (it takes only `input_audio`), the undocumented `sample_rate` on
163
+ `ONNXModel`'s constructor, and a copy-pasted "Destructor for
164
+ FacebookDenoiser" on `SpeechBrainDenoiser`. Also: README's relative links
165
+ to `checklist.md`/`audioflux_issues.md`/`CONTRIBUTING.md` only resolve if
166
+ those files are in Doxygen's `INPUT` (added), and Doxygen's markdown
167
+ parser choked on two multi-line `**bold**` spans and a `__repr__`-style
168
+ dunder name in `checklist.md` (reworded).
132
169
  - [x] Fixed `bind_audio` (the `_audio` module): it referenced a nonexistent
133
170
  `speech::Audio::sampleRate()` (the real method is `sample_rate()`) --
134
171
  this binding never actually compiled before.
@@ -219,9 +256,61 @@ ctoon's `tests/python/CMakeLists.txt` pattern:
219
256
  all 37 DSP tests *and* all 8 Python tests in one command; `ctest` shows
220
257
  both `speech_dsp` and `speech_python` entries; `-DBUILD_MODELS=OFF`
221
258
  (DSP-only) still works correctly with no Python target present.
222
- - [ ] Coverage reporting (lcov/coverage.py + merged dashboard) -- ctoon has
223
- an elaborate version of this; not set up here yet, out of scope for now.
224
-
259
+ - [x] Coverage reporting, modeled on ctoon's flow: a `speech_coverage_<component>`
260
+ target per component (`cpp_dsp`, `cpp_models`, `python`), a merged
261
+ `speech_coverage_total` (lcov `--add-tracefile`), a JSON-driven dashboard at
262
+ `build/coverage/index.html` (template, iframe wrapper, `genhtml.css` and the
263
+ `FixLCovPaths`/`GenerateIframe` scripts copied from ctoon and rebranded), a
264
+ `speech_coverage` umbrella, and a `build-coverage` CI job that runs the
265
+ umbrella and uploads `coverage/total/coverage.lcov` to Codecov. Verified by
266
+ actually running the whole umbrella locally (`BUILD_MODELS=ON BUILD_TESTS=ON
267
+ BUILD_PYTHON=ON BUILD_COVERAGE=ON`): all three components + merge + dashboard
268
+ build, dashboard data parses and lists total/cpp_dsp/cpp_models/py, and the
269
+ DSP-only configuration (`BUILD_MODELS=OFF`) and a normal coverage-off build
270
+ (5/5 ctest) still work. Numbers at the time: `speech::dsp` 82.7% lines /
271
+ 89.7% functions / 38.4% branches, `speech::models` 21.3% / 22.6% / 25.5%
272
+ (only 7 C++ tests so far, and the denoiser/VAD paths need model weights),
273
+ Python package 37% (see the dead-code item below).
274
+ Differences from ctoon, all deliberate: (1) gated on an explicit
275
+ `BUILD_COVERAGE` option, not merely on lcov being installed -- `speech_dsp`/
276
+ `speech_models` are real STATIC libraries with other consumers (`example`,
277
+ `speech`, the bindings), and gating on `find_program(lcov)` alone broke the
278
+ *normal* build wherever lcov happened to be installed (`undefined reference
279
+ to '__gcov_init'`); the instrumented libraries now export `--coverage` as a
280
+ PUBLIC *link* option so consumers always link libgcov; (2) `lcov --summary`
281
+ instead of `--list`, because `--list` in lcov 2.0-1 (Ubuntu 24.04) prints
282
+ wrong columns (4.8% for a file whose record says LF:21 LH:21, function
283
+ "rates" of 7200%) while `--summary` matches the raw LF/LH/FNF/FNH counters;
284
+ (3) `--exclude '*/src/third_party/*' --ignore-errors unused` at capture time
285
+ (a vendored aixlog lambda triggers a gcov "mismatched end line" hard error
286
+ otherwise; and lcov 2.x treats a pattern that matches nothing as an error),
287
+ and `--rc branch_coverage=1`/`--branch-coverage` on *every* lcov/genhtml
288
+ call -- that missing flag on `--extract` is why branch coverage earlier
289
+ showed "no data found". No Go/Rust/Julia/MATLAB/Zig parts, since libspeech
290
+ has none of those bindings.
291
+ - [x] Removed the `dr_libs` submodule -- it was pure duplication.
292
+ `miniaudio.h` already vendors its own renamed copy of dr_wav/dr_mp3/dr_flac
293
+ internally (search `dr_wav_h begin`/`dr_flac_h begin`/`dr_mp3_h begin` in
294
+ it -- same upstream author, kept in sync) and exposes all three uniformly
295
+ through `ma_decoder`/`ma_encoder` (`ma_encoding_format_{wav,flac,mp3}`),
296
+ including WAV encoding. Rewrote `src/audio.cpp`'s `loadWAV`/`loadMP3`/
297
+ `loadFLAC` into one shared `loadWithMiniaudio()` helper (encoding format
298
+ passed explicitly, so a mismatched extension still fails the same way the
299
+ old per-format `dr_*_init_*` calls did) and `saveWAV` to use
300
+ `ma_encoder_init_file`/`ma_encoder_write_pcm_frames`; dropped the
301
+ `dr_wav.h`/`dr_mp3.h`/`dr_flac.h` includes and their `DR_*_IMPLEMENTATION`
302
+ macros entirely. `speech_io`'s CMake target, `.gitmodules`, and the
303
+ submodule-init line in `README.md`/`CONTRIBUTING.md`/
304
+ `src/third_party/README.md` all updated to drop `dr_libs`; actually ran
305
+ `git submodule deinit`/`git rm` for it, not just deleted the directory.
306
+ Verified with real audio, not just a compile: `ffmpeg`-generated WAV/MP3/
307
+ FLAC (mono) + a stereo FLAC loaded correctly (right sample rate/channel
308
+ count/duration for all four); WAV and FLAC (both lossless) decoded to
309
+ bit-identical samples; MP3's duration came out ~10% longer than the
310
+ source, which is the format's own encoder priming/padding delay, not a
311
+ regression (same file, same padding would occur with dr_mp3 too); the
312
+ existing `test_save_and_load_wav_round_trip` pytest and the full `ctest`
313
+ suite (5/5) still pass.
225
314
  ## Python bindings for speech::models
226
315
 
227
316
  - [x] New `bind_models` module (`_models`, re-exported as
@@ -233,7 +322,7 @@ ctoon's `tests/python/CMakeLists.txt` pattern:
233
322
  - [x] `SileroVad`: full constructor (all tunable parameters), `.process()`,
234
323
  `.get_speech_timestamps()`, `.reset()`.
235
324
  - [x] `SpeechTimestamp`: `start`/`end` (samples), `start_s`/`end_s`
236
- (seconds), `__repr__`, `__eq__`.
325
+ (seconds), plus the `repr`/`eq` dunder methods.
237
326
  - [x] Found + fixed a real, pre-existing bug while testing this binding:
238
327
  `timestamp_t::start_s()`/`end_s()` (`include/libspeech/models/silero_vad.h`)
239
328
  performed integer division (`start / sample_rate`, both `int`), always
@@ -490,9 +579,8 @@ Previously: `speech_dsp`/`speech_io`/`speech_models` (C++ static libs) but
490
579
  benchmark seemed to show ~24% improvement (82ms -> 62ms), but a more
491
580
  careful re-run (20 reps, warm-up excluded) showed the before/after times
492
581
  are statistically indistinguishable (62.84ms vs. 61.78ms) -- the initial
493
- result was cold-start/measurement noise, not a real effect. **Needs
494
- re-benchmarking on an actual multi-core machine** to confirm the
495
- expected real-world speedup before this can be claimed anywhere.
582
+ result was cold-start/measurement noise, not a real effect. **Needs re-benchmarking on an actual multi-core machine**
583
+ to confirm the expected real-world speedup before this can be claimed anywhere.
496
584
  - Other identified-but-not-yet-pursued speed opportunities (same
497
585
  benchmark-first discipline applies before acting on any of these):
498
586
  flat/contiguous buffers instead of `vector<vector<float>>` for
@@ -0,0 +1,9 @@
1
+ # Read the content of the coverage file
2
+ file(READ ${COV_FILE} CONTENT)
3
+
4
+ # Replace the absolute source path with an empty string
5
+ # To relative paths like: include/...
6
+ string(REPLACE "SF:${SOURCE_PATH}" "SF:${PREFIX_PATH}" CONTENT "${CONTENT}")
7
+
8
+ # Write the modified content back to the file
9
+ file(WRITE ${COV_FILE} "${CONTENT}")