speecht5.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { WaveFile } from 'wavefile';
  2. import { updateFileProgress } from "@/utils/progress";
  3. import { convertNumberToWordsEN } from "@/utils/numberSpelling";
  4. export async function speecht5(
  5. message: string,
  6. speakerEmbeddingsUrl: string,
  7. ) {
  8. // empty cache
  9. (<any>window).chatvrm_worker_speecht5_audiocache = null;
  10. message = message.trim().split(/(-?\d+)/).map((s) => {
  11. if (s.match(/^-?\d+$/)) {
  12. return convertNumberToWordsEN(parseInt(s));
  13. } else {
  14. return s;
  15. }
  16. }).join("");
  17. // initialize worker if not already initialized
  18. if (! window.hasOwnProperty('chatvrm_worker_speecht5')) {
  19. (<any>window).chatvrm_worker_speecht5 = new Worker(new URL("../../workers/speecht5.js", import.meta.url), {
  20. type: "module",
  21. });
  22. (<any>window).chatvrm_worker_speecht5.addEventListener("message", (event: any) => {
  23. const message = event.data;
  24. // console.log(message);
  25. switch (message.status) {
  26. case "ready":
  27. console.log("speecht5 worker ready");
  28. break;
  29. case "progress":
  30. updateFileProgress(message.file, message.progress);
  31. break;
  32. case "done":
  33. console.log("speecht5 done: ", message.file);
  34. updateFileProgress(message.file, 100);
  35. break;
  36. case "complete":
  37. console.log("speecht5 complete");
  38. (<any>window).chatvrm_worker_speecht5_audiocache = message.data.audio;
  39. break;
  40. }
  41. });
  42. }
  43. // clear cache
  44. (<any>window).chatvrm_worker_speecht5_audiocache = null;
  45. // start job
  46. (<any>window).chatvrm_worker_speecht5.postMessage({
  47. text: message,
  48. speaker_embeddings: speakerEmbeddingsUrl,
  49. });
  50. // wait for job to complete
  51. await new Promise(async (resolve) => {
  52. console.log("speecht5 waiting for job to complete");
  53. while (true) {
  54. if((<any>window).chatvrm_worker_speecht5_audiocache !== null) {
  55. resolve(null);
  56. break;
  57. }
  58. await new Promise((resolve) => setTimeout(resolve, 100));
  59. }
  60. });
  61. let wav = new WaveFile();
  62. wav.fromScratch(1, 16000, '32f', (<any>window).chatvrm_worker_speecht5_audiocache);
  63. const wavBuffer = wav.toBuffer();
  64. const wavBlob = new Blob([wavBuffer], { type: 'audio/wav' });
  65. const arrayBuffer = await wavBlob.arrayBuffer();
  66. return { audio: arrayBuffer };
  67. }