shreyask commited on
Commit
7cc7cf8
·
verified ·
1 Parent(s): ff1919e

v0.2 polish: per-voice default speeds + trailing audio pad

Browse files

- voicepacks.json: Asha 0.85, Vivek 0.9, Mukta 0.9, Dnyanesh 0.9
(matches v0.1 Asha/Vivek natural-pace docs; SPRINGLab voices
sound natural at the same range per listening tests)
- main.ts: 80 ms trailing pad after last chunk's audio so ISTFTNet
output's final phoneme release transient isn't clipped at buffer
edge — fixes "last word eaten" perception across all voicepacks

README.md CHANGED
@@ -6,7 +6,6 @@ colorTo: red
6
  sdk: static
7
  pinned: false
8
  license: apache-2.0
9
- short_description: Marathi TTS in the browser — Kokoro-82M fine-tune, WebGPU
10
  models:
11
  - shreyask/bol-tts-marathi-onnx
12
  tags:
@@ -19,7 +18,7 @@ tags:
19
 
20
  # bol-tts-marathi — Marathi TTS via WebGPU
21
 
22
- In-browser Marathi (मराठी) text-to-speech, running real-time on WebGPU. Four voices, code-switch (Minglish) support, no server round-trip.
23
 
24
  This Space ships **both the built demo** (`index.html` + `assets/` served directly) **and the full source** (`src/`, `package.json`, `tsconfig.json`, `vite.config.ts`) so anyone can fork the Space and rebuild without de-minifying the bundle.
25
 
@@ -28,7 +27,7 @@ This Space ships **both the built demo** (`index.html` + `assets/` served direct
28
  | Path | Role |
29
  |---|---|
30
  | `index.html`, `assets/*` | built demo, served via static SDK |
31
- | `voices/*.bin` | 4 voicepacks (style vectors, 522 KB each) |
32
  | `voicepacks.json` | source-of-truth for voice list + per-gender test phrases |
33
  | `src/` | TypeScript source (phonemizer, tokenizer, model wrapper, UI wiring) |
34
  | `public/` | static assets fed to the build |
@@ -50,19 +49,21 @@ npm run build # produces dist/ — same artifacts shipped here
50
  - 82M-parameter Kokoro fine-tune for Marathi (model: [`shreyask/bol-tts-marathi-onnx`](https://huggingface.co/shreyask/bol-tts-marathi-onnx))
51
  - `@huggingface/transformers` loads the ONNX model into WebGPU (or falls back to WASM)
52
  - `espeak-ng-wasm` phonemizes Marathi + Indian English; we parse `(en)/(mr)` tags for per-segment Indian-accent rules on English chunks
53
- - 4 voices via single shared model + per-voice 256-D style vectors (`voices/*.bin`, [510, 1, 256] float32)
54
  - Test phrases + voice metadata in `voicepacks.json` — edit to add voices, no code changes needed
55
 
56
  Recipe + training scripts: [github.com/shreyaskarnik/bol-tts-marathi](https://github.com/shreyaskarnik/bol-tts-marathi)
57
 
58
  ## Voices
59
 
60
- | ID | Name | Gender | Source | Voicepack origin |
61
  |---|---|---|---|---|
62
- | `mf_asha` | Asha (आशा) | female | Rasa Marathi | v0.1 voicepack on v0.2 model |
63
- | `mm_vivek` | Vivek (विवेक) | male | Rasa Marathi | v0.1 voicepack on v0.2 model |
64
- | `mf_mukta` | Mukta (मुक्ता) | female | SPRINGLab IndicTTS | v0.2 voicepack on v0.2 model |
65
- | `mm_dnyanesh` | Dnyanesh (ज्ञानेश) | male | SPRINGLab IndicTTS | v0.2 voicepack on v0.2 model |
 
 
66
 
67
  ## License
68
 
 
6
  sdk: static
7
  pinned: false
8
  license: apache-2.0
 
9
  models:
10
  - shreyask/bol-tts-marathi-onnx
11
  tags:
 
18
 
19
  # bol-tts-marathi — Marathi TTS via WebGPU
20
 
21
+ In-browser Marathi (मराठी) text-to-speech, running real-time on WebGPU. Six voices, code-switch (Minglish) support, no server round-trip.
22
 
23
  This Space ships **both the built demo** (`index.html` + `assets/` served directly) **and the full source** (`src/`, `package.json`, `tsconfig.json`, `vite.config.ts`) so anyone can fork the Space and rebuild without de-minifying the bundle.
24
 
 
27
  | Path | Role |
28
  |---|---|
29
  | `index.html`, `assets/*` | built demo, served via static SDK |
30
+ | `voices/*.bin` | 6 voicepacks (style vectors, 522 KB each) |
31
  | `voicepacks.json` | source-of-truth for voice list + per-gender test phrases |
32
  | `src/` | TypeScript source (phonemizer, tokenizer, model wrapper, UI wiring) |
33
  | `public/` | static assets fed to the build |
 
49
  - 82M-parameter Kokoro fine-tune for Marathi (model: [`shreyask/bol-tts-marathi-onnx`](https://huggingface.co/shreyask/bol-tts-marathi-onnx))
50
  - `@huggingface/transformers` loads the ONNX model into WebGPU (or falls back to WASM)
51
  - `espeak-ng-wasm` phonemizes Marathi + Indian English; we parse `(en)/(mr)` tags for per-segment Indian-accent rules on English chunks
52
+ - 6 voices via single shared model + per-voice 256-D style vectors (`voices/*.bin`, [510, 1, 256] float32)
53
  - Test phrases + voice metadata in `voicepacks.json` — edit to add voices, no code changes needed
54
 
55
  Recipe + training scripts: [github.com/shreyaskarnik/bol-tts-marathi](https://github.com/shreyaskarnik/bol-tts-marathi)
56
 
57
  ## Voices
58
 
59
+ | ID | Name | Gender | Source | Status |
60
  |---|---|---|---|---|
61
+ | `mf_asha` | Asha (आशा) | female | Rasa Marathi | stable |
62
+ | `mm_vivek` | Vivek (विवेक) | male | Rasa Marathi | stable |
63
+ | `mf_mukta` | Mukta (मुक्ता) | female | IndicVoices-R | stable |
64
+ | `mm_dnyanesh` | Dnyanesh (ज्ञानेश) | male | IndicVoices-R | stable |
65
+ | `mf_priya` | Priya (प्रिया) | female | SPRINGLab IndicTTS | v0.2 preview |
66
+ | `mm_arjun` | Arjun (अर्जुन) | male | SPRINGLab IndicTTS | v0.2 preview |
67
 
68
  ## License
69
 
assets/index-B2DCZUEd.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:730e27728d87c38794231d4bf98054a830d90a44af363bfb99fa9b49373d38b2
3
+ size 19064872
index.html CHANGED
@@ -17,7 +17,7 @@
17
  rel="stylesheet"
18
  />
19
 
20
- <script type="module" crossorigin src="/assets/index-DEWyyPqu.js"></script>
21
  <link rel="stylesheet" crossorigin href="/assets/index-BdhRcMoO.css">
22
  </head>
23
  <body>
 
17
  rel="stylesheet"
18
  />
19
 
20
+ <script type="module" crossorigin src="/assets/index-B2DCZUEd.js"></script>
21
  <link rel="stylesheet" crossorigin href="/assets/index-BdhRcMoO.css">
22
  </head>
23
  <body>
public/voicepacks.json CHANGED
@@ -8,7 +8,7 @@
8
  "name_native": "आशा",
9
  "gender": "female",
10
  "source": "rasa",
11
- "default_speed": 1.0,
12
  "ship_status": "stable"
13
  },
14
  {
@@ -17,7 +17,7 @@
17
  "name_native": "विवेक",
18
  "gender": "male",
19
  "source": "rasa",
20
- "default_speed": 1.0,
21
  "ship_status": "stable"
22
  },
23
  {
@@ -26,7 +26,7 @@
26
  "name_native": "मुक्ता",
27
  "gender": "female",
28
  "source": "springlab",
29
- "default_speed": 1.0,
30
  "ship_status": "stable"
31
  },
32
  {
@@ -35,7 +35,7 @@
35
  "name_native": "ज्ञानेश",
36
  "gender": "male",
37
  "source": "springlab",
38
- "default_speed": 1.0,
39
  "ship_status": "stable"
40
  }
41
  ],
 
8
  "name_native": "आशा",
9
  "gender": "female",
10
  "source": "rasa",
11
+ "default_speed": 0.85,
12
  "ship_status": "stable"
13
  },
14
  {
 
17
  "name_native": "विवेक",
18
  "gender": "male",
19
  "source": "rasa",
20
+ "default_speed": 0.9,
21
  "ship_status": "stable"
22
  },
23
  {
 
26
  "name_native": "मुक्ता",
27
  "gender": "female",
28
  "source": "springlab",
29
+ "default_speed": 0.9,
30
  "ship_status": "stable"
31
  },
32
  {
 
35
  "name_native": "ज्ञानेश",
36
  "gender": "male",
37
  "source": "springlab",
38
+ "default_speed": 0.9,
39
  "ship_status": "stable"
40
  }
41
  ],
src/main.ts CHANGED
@@ -476,6 +476,18 @@ async function onSynth() {
476
  audioOffsetSamples += PAD_SAMPLES;
477
  }
478
  }
 
 
 
 
 
 
 
 
 
 
 
 
479
  const t1 = performance.now();
480
 
481
  // Concat audio into one Float32Array for the WAV encoder + waveform.
 
476
  audioOffsetSamples += PAD_SAMPLES;
477
  }
478
  }
479
+
480
+ // Trailing pad after the final chunk. ISTFTNet decoder produces samples
481
+ // up to the last predicted phoneme's duration with no acoustic decay
482
+ // buffer — without this pad, the very end of the audio file ends mid-
483
+ // release-transient and listeners perceive the last word as "eaten".
484
+ // 80 ms is enough to cover any voicepack's natural release without
485
+ // making the end feel laggy.
486
+ const TRAIL_PAD_SEC = 0.08;
487
+ const TRAIL_PAD_SAMPLES = Math.floor(sampleRate * TRAIL_PAD_SEC);
488
+ allAudio.push(new Float32Array(TRAIL_PAD_SAMPLES));
489
+ audioOffsetSamples += TRAIL_PAD_SAMPLES;
490
+
491
  const t1 = performance.now();
492
 
493
  // Concat audio into one Float32Array for the WAV encoder + waveform.
voicepacks.json CHANGED
@@ -8,7 +8,7 @@
8
  "name_native": "आशा",
9
  "gender": "female",
10
  "source": "rasa",
11
- "default_speed": 1.0,
12
  "ship_status": "stable"
13
  },
14
  {
@@ -17,7 +17,7 @@
17
  "name_native": "विवेक",
18
  "gender": "male",
19
  "source": "rasa",
20
- "default_speed": 1.0,
21
  "ship_status": "stable"
22
  },
23
  {
@@ -26,7 +26,7 @@
26
  "name_native": "मुक्ता",
27
  "gender": "female",
28
  "source": "springlab",
29
- "default_speed": 1.0,
30
  "ship_status": "stable"
31
  },
32
  {
@@ -35,7 +35,7 @@
35
  "name_native": "ज्ञानेश",
36
  "gender": "male",
37
  "source": "springlab",
38
- "default_speed": 1.0,
39
  "ship_status": "stable"
40
  }
41
  ],
 
8
  "name_native": "आशा",
9
  "gender": "female",
10
  "source": "rasa",
11
+ "default_speed": 0.85,
12
  "ship_status": "stable"
13
  },
14
  {
 
17
  "name_native": "विवेक",
18
  "gender": "male",
19
  "source": "rasa",
20
+ "default_speed": 0.9,
21
  "ship_status": "stable"
22
  },
23
  {
 
26
  "name_native": "मुक्ता",
27
  "gender": "female",
28
  "source": "springlab",
29
+ "default_speed": 0.9,
30
  "ship_status": "stable"
31
  },
32
  {
 
35
  "name_native": "ज्ञानेश",
36
  "gender": "male",
37
  "source": "springlab",
38
+ "default_speed": 0.9,
39
  "ship_status": "stable"
40
  }
41
  ],