{"_id":"@aituber-onair/voice","_rev":"25-1edb08463a33456e36814a6565b47da4","name":"@aituber-onair/voice","dist-tags":{"latest":"0.21.0"},"versions":{"0.1.0":{"name":"@aituber-onair/voice","version":"0.1.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.1.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"3913b6272346e6a74398c2bd082132ca1bd48798","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.1.0.tgz","fileCount":42,"integrity":"sha512-4eFf4AP2n5gWZyXECeLKfUYta9NefxqwYjyVVQflVIlK1uMCsm113aI7NjcnBKNxtUrfF9kGy35t3kPHyMgWKQ==","signatures":[{"sig":"MEUCIGYm7KTCQWHE777SSlN3sC7Xs1pFNWVJfFZemLb3F8UxAiEAii4OVNKcrXlHtWYVEDxw8BpeY+BlvqoXrm1SVVOrFu4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74663},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"67776d0bf5a3560a78bf8550c1d8211facbb17cc","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"tsc --project tsconfig.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","actor":{"name":"shinshin86","type":"user","email":"shinshin86npm@gmail.com"},"email":"shinshin86npm@gmail.com"},"_npmVersion":"10.9.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"22.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.1.0_1751457140546_0.919360057032627","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aituber-onair/voice","version":"0.1.1","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.1.1","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"bcf88ae9e56ebb44337f53835785ff6a8b149ac9","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.1.1.tgz","fileCount":42,"integrity":"sha512-axkXsX9Bbc5ljDgGIxh3zcbVLJrSdM62KTKXAQUS2nnIAzpjJdlQqdCvVimVJLwhDXG5ElccW8GM6Sn+EkOdSQ==","signatures":[{"sig":"MEQCIGLcgCx/1m+om4I33sNOxXTD/EGUGY91iRR3NQpA4yQcAiAeyBko2825CRWKxUllVXguMb5s8eMvd9hDMEFJdb1E1A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74765},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"22b16002a46d65cea9de379cdc35b84a249263dc","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"tsc --project tsconfig.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","actor":{"name":"shinshin86","type":"user","email":"shinshin86npm@gmail.com"},"email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.1.1_1751463960542_0.26914154337657026","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aituber-onair/voice","version":"0.2.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.2.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"fc65c109e99b6a182d1eead569243f947e47b19d","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.2.0.tgz","fileCount":106,"integrity":"sha512-Yszg3bYgJdcT2Dxc/NeJ1dSufMEq5s3RwCL+BSECRllZOV2TWe4ApeWQKCWjq/1CGkhJaSFTrT6wXEiJfFa4OA==","signatures":[{"sig":"MEQCIFVwwOMoUP1cHWiohzlj0uzKn/kb8coxZFWFClsXHobjAiBf25QFn2zkve+V1OIs94Jl+0N8gRThTT0BkBGoyjTHVg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":177369},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"}},"gitHead":"1909a3c2cab2bfbf0ba1e65acb178bcd98d47851","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","actor":{"name":"shinshin86","type":"user","email":"shinshin86npm@gmail.com"},"email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.2.0_1751955701354_0.2803418593783149","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aituber-onair/voice","version":"0.2.1","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.2.1","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"ab0f499ea2f884616832028062b6e60dd3f490d0","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.2.1.tgz","fileCount":106,"integrity":"sha512-RARiZUL0yqm57DJwRcMgkagPAPvyYDnrHQkWGdabU2cctfTLGSmr4qt6yBf5x+M1YklxcJBUc/1dEtIFWDxNKg==","signatures":[{"sig":"MEUCIQCUN1OXpgIWqIw4tNaJRPXNNhIXfGbJjehaBIroHuspUgIgMmZCX5tEbHrTYkAOOToDtZkx22eFOqcSuzxdcEjBeR8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":177441},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"4f4c8577c4a723bc2e7c403c2360166b8587766b","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","actor":{"name":"shinshin86","type":"user","email":"shinshin86npm@gmail.com"},"email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.2.1_1751959115420_0.9887357127818346","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aituber-onair/voice","version":"0.3.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.3.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"cb831930189f8036c34079b52b78d42d40998380","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.3.0.tgz","fileCount":110,"integrity":"sha512-MiQ3Q4wk/FQIdOr2OetgGYEPvS3/jdyvxjVL2Ocu0Fq+2bGxUH7CX4KasF5cp1D+zLasstoX6RVVwfn59PZL4A==","signatures":[{"sig":"MEUCIQCIAQLgoWRINiIi/c3rWk7JD4irdk0QLFY8iy+U4F4kJwIgX6K5cRCupGbv2TZ3hdFtUuWBEmPFbAIwf/914/7UElE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":217236},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"f8ee46ce249fbf75d53c41e6fcb5be1293b5c57c","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.4","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.3.0_1753243419366_0.376882618881357","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aituber-onair/voice","version":"0.4.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.4.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"01f985754c18e79263815da366c9b9f80a48e0a5","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.4.0.tgz","fileCount":110,"integrity":"sha512-qQOeJcgfwJZxsHYtWCBopWXWgE5WjfABAdisr7jKh2CdVkB2EVioVnkpWBo7s5GNoImLhJO4pr09yZbFp11eug==","signatures":[{"sig":"MEQCIBoycjkxq5K8xpyMSeoi+q/Godmkr/PmM1lzsTKZeMccAiAUqC2i5F3Kz4PW34BkiZi3aZekgrb4ZSlbTLUSo7eZHw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":219170},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"0772baae7ad304bf350d947eea1357a87f5ae923","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.4","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.4.0_1756345897759_0.0830224065583689","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aituber-onair/voice","version":"0.5.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.5.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"2326ec779b264b0ce85d90552efff4d99b5102db","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.5.0.tgz","fileCount":110,"integrity":"sha512-H8JUlmLpze2dY7CAir6i74b5JTp0DVdAticfVSHHx8Crn8NU/1V7Evmw6qRX7CRYkd4i5Q6zoLqfXT8jjX25QQ==","signatures":[{"sig":"MEYCIQCpPs9A6iE13+FsZSYcRVE1aZBpflibFLs0MnJ9UvEftwIhAK7wgYlMxGVTdYVUjgmIrihFyi8QPmd8GDNX0vhlO9yd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":301591},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"f6258f1a2fd9f65ba679163112aeb6dabc4df765","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.5.0_1761870486360_0.7513545915328765","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@aituber-onair/voice","version":"0.5.1","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.5.1","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"dcdde15c8431d2c31727afc87f390d9982cc24fa","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.5.1.tgz","fileCount":110,"integrity":"sha512-T1V44jDGrmChvB5UGQzmXB3EEu/d4tsrxfxKboRjzsrohpRuBLciy2ekbiQFtQ3wA/pcl8kHZnSy+eUYfE0ccg==","signatures":[{"sig":"MEUCIQClJOKU9+uBv/2x0Y882j1TfqdyXSKpOwpxL/NtkSqoDwIgZdvp1YRPrv8l9KdeAG0P5XCiVXHCfEceNFsG16jTO/4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":304805},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"9308e40f57dac84363f6aee93b9c51c0aefb185a","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.5.1_1761897281779_0.18405975115651252","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@aituber-onair/voice","version":"0.6.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.6.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"61110c1a985a25944a793ac0595a2c726ffaa6fd","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.6.0.tgz","fileCount":110,"integrity":"sha512-Qxd0Xf4O3WgaRMRSsdPRrosIAiUw97juOKbabfLIGKA7NC7xXs1vJkQEHx8fesV142RjrzyTCKmDa2rZdDBdMw==","signatures":[{"sig":"MEQCIFM7E5uNwzJ2JnCyrYC3UK6VGz3CKXYacJY3B9n7N794AiBedw81QozTyCtYfy/7Kw8rw82k9XrlFYbYZuZtw+P6jg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":306907},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"d90f437f0e2fa1ea839f5638c4194aa283e3831c","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.6.0_1762486186075_0.6444356240481663","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@aituber-onair/voice","version":"0.7.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.7.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"89a642bc6757dbebcb1e142b974756717e0e369f","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.7.0.tgz","fileCount":110,"integrity":"sha512-1l/638MwhwdVd70GDjePYPInFzxjd/+/Uwda4RqkI1si0zhzeApxoPAXEcNFonrgH7yb10mpndGntp7hRObX3g==","signatures":[{"sig":"MEUCIQCHH9Pzox3zwtOamWz5E9FS31DpSqS7IZxSc2WJ7g1uOwIgdHobwymwvTZkzui2Q+yN9CxRpnHx2SL9it4ANz4bGhg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":307537},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"0e3382927f79f08cec578718aa23398830f65117","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.7.0_1762813125902_0.21541649298768073","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@aituber-onair/voice","version":"0.8.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.8.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"3474a24de3dc8a7534ee3112ff24b10bdca81b80","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.8.0.tgz","fileCount":106,"integrity":"sha512-OI5Vrfu0WxKI6VKFaMxcm1R+hiAXbgemLARfH/zX+DG6KL7bB4mfvqkqOJqL9blCD2DN5mSMI/paGELg+qDNgg==","signatures":[{"sig":"MEQCIFx+PZNj6ZvdamBaycAvQSwXopLoXSwkrE29+n79wKvFAiASm6ZjDdxIAB+FGid3BNo44QYAJpzbSsIf+gA5ylJ7Bw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":294387},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"d8de8e21cc6bb5e4597e246ee8f26b7266bbbce3","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.8.0_1769835086707_0.28429949708282964","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@aituber-onair/voice","version":"0.9.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.9.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"78695fe51cf385c1f77b00a370901f15a491eb6e","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.9.0.tgz","fileCount":150,"integrity":"sha512-PDakfbjVkzDN0DBpnp19spcfZsCQDZOKYQSEHjl5Ca4/8Ud+SCmZZzU7axbLblZMNUp/CjO260HeWOE0SRPWRw==","signatures":[{"sig":"MEQCIH+IxRKQxk+qyqBdBd3mzuJx+aLJqNwvhE54zPI3JErmAiBDyzlXy/LXUe2lKmTOl0qtpbOVvsOpITPrbP1D48lC4g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":335340},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"918e26e8898625f0f2e8dfa5c54d4c040e901cb6","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.9.0_1774081237107_0.29180826822656325","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@aituber-onair/voice","version":"0.10.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.10.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"37fcc9a58bf752d2325be77c8aa5ede8d13d7a58","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.10.0.tgz","fileCount":158,"integrity":"sha512-MEXa6dIx1SECSPEnpcNYMYedIB16CB/7nHxpuz47tkK/YcLBP3L1724jykdQI7eRdQKZnuTtxOaFEYO/XRu+kg==","signatures":[{"sig":"MEUCIQCAdo0pVWHj+p8jIgegMmbVGk1A1SEpYzJh6oVrbe5zgQIgeKGtCBa0wIvmS1VUWnmBfIVfz+W1xw7WNO0SYJjOamY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":349632},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"82360610a7c617651c1f0bafced671d24d361e37","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.10.0_1775351271718_0.9264949194308161","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@aituber-onair/voice","version":"0.11.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.11.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"b40d70cd2fcf48ff6f1055427866d5ab8f8a58be","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.11.0.tgz","fileCount":166,"integrity":"sha512-z8+1eWPeoPAOnR5ww3pLroHfFzrVfWdvyLArYtWQlIJvnUTmKQC9dQVw//WINNIHYs9o5dPOfSQXVBMNg5bI9g==","signatures":[{"sig":"MEQCIDanO0SzDE5W7E2iozX6w/eZLqm8u5yCzlsjuF8IytHEAiA46ulbRY8x1AaZfYHw1ZCAWaTUQkPHZ0Q19dCK0YhDXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":369015},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"a9615dc66ffff8c4de26215b9a701a71c7735833","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.11.0_1775512443486_0.17884499894515216","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@aituber-onair/voice","version":"0.12.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.12.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"37d9a71daaafb608249af88c26d8f14e06c7e049","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.12.0.tgz","fileCount":174,"integrity":"sha512-obLpkRc0SDEc5gWL5Lb1rpoM8TywAzxsrIcwSOxqmresh+RP1C/l4NU3mZOk9/WOkwmc8aVzI432pyjTaPxJMQ==","signatures":[{"sig":"MEQCIDyj7lWH9hea88ae9bMJbp5e4bYXHg/Zhp4yoH+7o4JpAiAd7/ZDCvPHbxd059WrNvZT5TxgM6djbO2/PNeDYLM7yQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":403275},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"d2bb3fccc4a04802ea90b642d55b9c4e614e783c","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.12.0_1775646484976_0.7458977299321854","host":"s3://npm-registry-packages-npm-production"}},"0.12.1":{"name":"@aituber-onair/voice","version":"0.12.1","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.12.1","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"d430537a369b8e39ad8bdb0b74dcf38fd8fa5d6d","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.12.1.tgz","fileCount":174,"integrity":"sha512-rif2gaAI4GDtyMF27La8SAkRF5Sd9vTLzumVnRhbp0VQoh3WZUa+DZlVOLzh6LXLhZ4wBzraE1Th94rw7WAKKg==","signatures":[{"sig":"MEUCIQCyBzf3GH4tQCtCoKjQV0Oj9L0twMHCHbcgl/y6vfL5kQIgb1dQNY/hdIVNpKpvDu1OShP2tosIvGIEUjZ2tCUWXRo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":405003},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"654c5ddc5747990581cbe2ea9c0122af31f115a8","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.12.1_1775884601190_0.8973267404650771","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@aituber-onair/voice","version":"0.13.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.13.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"49d73580429d89a1e62d465298c450a5f4add142","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.13.0.tgz","fileCount":174,"integrity":"sha512-3DQSNS0cBtF1utSzJ8EZCu7q6fhwNLOha3fx505uGR97HZJcqMxr0apD6AVqoOoDxagYROitoyIeCrCMHDi0Zg==","signatures":[{"sig":"MEQCIDoTRYW7wKbsoaQNsRd/EcTzf8k0bIPPs/kFphZtA0cnAiA35bJmnDcahoml7fo+Lb4SeFtn9qyqC97Vts1asNO3KA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":405145},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"1f2184ce751079f7a7e32abe520c3d7912779d53","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.13.0_1776297068848_0.05083825555565702","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"@aituber-onair/voice","version":"0.14.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.14.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"206fa9bb35a5046ece2a452e38f112790cd49099","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.14.0.tgz","fileCount":174,"integrity":"sha512-TpDv4mPFwZ8Qd7/b6asGmzY7qQOnEYtOHUJsFN1Y3PpOBSKxGP6ju9umB9zjMH9/bfg65QNoN5pg9VGJjVMj3g==","signatures":[{"sig":"MEQCIAvFYJ86hUyStVc8nSmEX1sAF5qw7JLcwFYCbFD9bwE6AiBUv3EnGtLTL51fynI47OapnUxrczsvasdDEShrGLW9YA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":411051},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"38d2313f82bc7c38b8968a4a6ad522ba607779f9","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.14.0_1776758990799_0.5449112893075299","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"@aituber-onair/voice","version":"0.15.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.15.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"9b0a2bae2c69fa6363d4aa62bf58002fb41eec78","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.15.0.tgz","fileCount":190,"integrity":"sha512-Uk6Fh5indCAFCc8ej3dLDOkxa7ich2l6YbfLFmE7ZANjql7YyxJgcMc8hUyv2mlhZl+a11666rWnk9ixLeadNg==","signatures":[{"sig":"MEQCIA+3vz7wMmfVzkOU1/kOZttm9CpI+ZQQ2/MUF6MgQ6ObAiAAmcqeo096QSqlmy5VXZ0K1dftXIcvJvZZ9Juhk99s8A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":464508},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"4775f79d4c2eed2f25b885656b2c6da41097c68a","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.15.0_1777283946850_0.04852399021946252","host":"s3://npm-registry-packages-npm-production"}},"0.16.0":{"name":"@aituber-onair/voice","version":"0.16.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.16.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"08a4f96dfa89d4ac77693d5e8cbcdd958a6c1917","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.16.0.tgz","fileCount":198,"integrity":"sha512-awFKwi+gK/x1DqMX5htEWfqVz4/DZnn0W08t49kVlPC30otnh9fIekMVL+1wwMZaK2BDfD+E9sqh0lelndJx9A==","signatures":[{"sig":"MEUCICtgUzZ2es6RK+n0ygcVmIliCmAXQkchje1g3AM6aERJAiEA8qTExZFGHS+9+QuewbsD7HKvY8SHmPS2tBbRbtVwsls=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":490535},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"cd2ff33534e6d26bff1ad89d9c76e3c89f8ca1f8","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.16.0_1778766698871_0.2682465741283595","host":"s3://npm-registry-packages-npm-production"}},"0.17.0":{"name":"@aituber-onair/voice","version":"0.17.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.17.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"465daefe56742f1339a91e6d1d0ef322d44dd249","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.17.0.tgz","fileCount":206,"integrity":"sha512-eyUjhvGPglwKh7+FkeuTfegux9S8yt5+NGq6lC20k2KVQy1AqRJ0zrGHmdGFpXBX8zEut1rPzusTp+g0Pp1xyg==","signatures":[{"sig":"MEUCIQChh+hDAU1Yf/PbqizrtpJWJXsSJFcVBfG9Nc8AJFw12QIgdUpRlTcwXvUMYB3kvb8JA3ILMxzgTMYNl1Q7bdiDvUw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":514635},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"a3b25a776b6bbe79d62584a452453fc12fc44e04","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.17.0_1780090725917_0.730964844466524","host":"s3://npm-registry-packages-npm-production"}},"0.18.0":{"name":"@aituber-onair/voice","version":"0.18.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.18.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"e2f76b6c79727ab9e13cf5a18934c7140273311c","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.18.0.tgz","fileCount":226,"integrity":"sha512-zAJ7333B/LZJEjjnoCN6LILBP1FFhNzymGVRBVZb76GsapQVuq7cdNJgiO7sBx4wYI/yBQiy8WSX4MkOTV7wXA==","signatures":[{"sig":"MEQCIBhMZj8gwXR8thTGERU2MPOyKly6O4ceQQTDbkRct+JSAiAgk/0WfqKMcMjl0WPbNtc1uujhbsVo+/Efz0pSRtKPdg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":550011},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"607997e5c69fa0df716080ca0c5cf07a86802f24","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.18.0_1782886491727_0.6787175304070705","host":"s3://npm-registry-packages-npm-production"}},"0.19.0":{"name":"@aituber-onair/voice","version":"0.19.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.19.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"341aad5ca9555b818fc2506a464422ba62ec6c44","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.19.0.tgz","fileCount":234,"integrity":"sha512-bgJRrxWVc0mm2DvDpY1oSS4rvSMDbjPQgCRTzCTXHsL2pWeirWP4tm+PoHR3l4gRHtcITSlnJ9rYGYWuk7il4w==","signatures":[{"sig":"MEUCIQC6u2fwOk6P47t0J3ISAAwxw2zcDsu7F1Ne6tb9P6a0JwIgOb9A/AadidPrIXJroNB4y03O/pZGPTuQuJLbmszcbng=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":576701},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"53b2f67982c2d7951e4c50ae8555b46cffc9d929","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.19.0_1783635030165_0.4618532606763692","host":"s3://npm-registry-packages-npm-production"}},"0.20.0":{"name":"@aituber-onair/voice","version":"0.20.0","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"url":"https://github.com/shinshin86","name":"shinshin86"},"license":"MIT","_id":"@aituber-onair/voice@0.20.0","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"dist":{"shasum":"56e2e6d0ac59a7945cd06da0de8b5e68ce25513b","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.20.0.tgz","fileCount":250,"integrity":"sha512-8wu4JFqkV55ijPR9LangzfclVA/7Qs8UeJUYtN9NHAlrE9aoV4JtrBpzS3RCer26dtuGFuZI1SWf3uHnmnUxpw==","signatures":[{"sig":"MEYCIQDCWhSQ6XnHzblI7Olme+qweC7utiZawe+vCcSNcJfMLwIhANG3GkjRuLelAijrsNX9QyznaS+rWC96UoU+f8VLeL+J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":620231},"main":"dist/cjs/index.js","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"gitHead":"e0764720010a07ccd2ccf27723ae4875346524bb","scripts":{"fmt":"biome format . --write","lint":"biome lint .","test":"npm run typecheck && vitest run","build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","fmt:check":"biome format .","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"_npmVersion":"10.8.2","description":"Voice synthesis library for AITuber OnAir","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^22.1.0","vitest":"^1.3.1","typescript":"^5.0.0","@types/node":"^18.15.0","@biomejs/biome":"1.9.4","@vitest/coverage-v8":"^1.3.1"},"_npmOperationalInternal":{"tmp":"tmp/voice_0.20.0_1786776944218_0.8343779595498129","host":"s3://npm-registry-packages-npm-production"}},"0.21.0":{"name":"@aituber-onair/voice","version":"0.21.0","description":"Voice synthesis library for AITuber OnAir","main":"dist/cjs/index.js","module":"dist/esm/index.js","types":"dist/cjs/index.d.ts","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"},"./dist/cjs/*":"./dist/cjs/*","./dist/esm/*":"./dist/esm/*"},"scripts":{"build":"npm run build:cjs && npm run build:esm","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","typecheck":"tsc --noEmit","test":"npm run typecheck && vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","fmt":"biome format . --write","fmt:check":"biome format .","lint":"biome lint .","prepublishOnly":"npm run build"},"keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"author":{"name":"shinshin86","url":"https://github.com/shinshin86"},"license":"MIT","devDependencies":{"@biomejs/biome":"1.9.4","@types/node":"^18.15.0","@vitest/coverage-v8":"^1.3.1","jsdom":"^22.1.0","typescript":"^5.0.0","vitest":"^1.3.1"},"publishConfig":{"access":"public"},"_id":"@aituber-onair/voice@0.21.0","gitHead":"1673d1be64f86103125e235535271168531ae50b","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-47FFreDP/xDWlSHZSQS9HadOENpVESVDL4/0mVbgwT1+FnCWwMFYAOqbjtkc/CU9k+oMlP/hIlSq4DN+u8XaSQ==","shasum":"b4057d5d0464b124c1526a2d0c016c95b8bf43f1","tarball":"https://registry.npmjs.org/@aituber-onair/voice/-/voice-0.21.0.tgz","fileCount":250,"unpackedSize":623507,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDpNgNp0jU8k8suxGid+Ij9AFqnUxzTek3qAeQC8068fgIgdi8P/KOt9pf2YZFnsjUfxflT3A9QWYZmRzlcA+EHcT8="}]},"_npmUser":{"name":"shinshin86","email":"shinshin86npm@gmail.com"},"directories":{},"maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/voice_0.21.0_1789133197105_0.7224017120910582"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-02T11:52:20.484Z","modified":"2026-09-11T13:26:37.517Z","0.1.0":"2025-07-02T11:52:20.748Z","0.1.1":"2025-07-02T13:46:00.754Z","0.2.0":"2025-07-08T06:21:41.587Z","0.2.1":"2025-07-08T07:18:35.589Z","0.3.0":"2025-07-23T04:03:39.560Z","0.4.0":"2025-08-28T01:51:37.964Z","0.5.0":"2025-10-31T00:28:06.625Z","0.5.1":"2025-10-31T07:54:41.961Z","0.6.0":"2025-11-07T03:29:46.282Z","0.7.0":"2025-11-10T22:18:46.111Z","0.8.0":"2026-01-31T04:51:26.861Z","0.9.0":"2026-03-21T08:20:37.275Z","0.10.0":"2026-04-05T01:07:51.882Z","0.11.0":"2026-04-06T21:54:03.612Z","0.12.0":"2026-04-08T11:08:05.124Z","0.12.1":"2026-04-11T05:16:41.331Z","0.13.0":"2026-04-15T23:51:08.992Z","0.14.0":"2026-04-21T08:09:50.938Z","0.15.0":"2026-04-27T09:59:07.006Z","0.16.0":"2026-05-14T13:51:39.010Z","0.17.0":"2026-05-29T21:38:46.083Z","0.18.0":"2026-07-01T06:14:51.868Z","0.19.0":"2026-07-09T22:10:30.302Z","0.20.0":"2026-08-15T06:55:44.342Z","0.21.0":"2026-09-11T13:26:37.312Z"},"author":{"name":"shinshin86","url":"https://github.com/shinshin86"},"license":"MIT","keywords":["aituber","vtuber","ai","voice","tts","speech-synthesis"],"description":"Voice synthesis library for AITuber OnAir","maintainers":[{"name":"shinshin86","email":"shinshin86npm@gmail.com"}],"readme":"# AITuber OnAir Voice\n\n![AITuber OnAir Voice - logo](https://github.com/shinshin86/aituber-onair/raw/main/packages/voice/images/aituber-onair-voice.png)\n\n[@aituber-onair/voice](https://www.npmjs.com/package/@aituber-onair/voice) is an independent voice synthesis library that supports multiple TTS (Text-to-Speech) engines. While originally developed for the [AITuber OnAir](https://aituberonair.com) project, it can be used standalone for any voice synthesis needs.\n\n[日本語版はこちら](https://github.com/shinshin86/aituber-onair/blob/main/packages/voice/README_ja.md)\n\nThis project is published as open-source software and is available as an [npm package](https://www.npmjs.com/package/@aituber-onair/voice) under the MIT License.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Installation](#installation)\n- [Main Features](#main-features)\n- [Basic Usage](#basic-usage)\n- [Supported TTS Engines](#supported-tts-engines)\n- [Emotion-Aware Speech](#emotion-aware-speech)\n- [Browser Compatibility](#browser-compatibility)\n- [Advanced Configuration](#advanced-configuration)\n- [Engine-Specific Features](#engine-specific-features)\n- [Integration with AITuber OnAir Core](#integration-with-aituber-onair-core)\n- [API Reference](#api-reference)\n- [Examples](#examples)\n- [Testing](#testing)\n- [Contributing](#contributing)\n\n## Overview\n\n**@aituber-onair/voice** is a comprehensive voice synthesis library that provides a unified interface for multiple TTS engines. It specializes in emotion-aware speech synthesis, making it ideal for creating expressive virtual characters, AI assistants, and interactive applications.\n\nKey design principles:\n- **Engine Independence**: Switch between TTS engines without changing your code\n- **Emotion Support**: Built-in emotion detection and synthesis\n- **Browser Ready**: Full support for web audio playback\n- **TypeScript First**: Complete type safety and excellent IDE support\n- **Zero Dependencies**: Minimal external dependencies for maximum compatibility\n\n## Installation\n\nInstall using npm:\n\n```bash\nnpm install @aituber-onair/voice\n```\n\nOr using yarn:\n\n```bash\nyarn add @aituber-onair/voice\n```\n\nOr using pnpm:\n\n```bash\npnpm install @aituber-onair/voice\n```\n\n## Main Features\n\n- **Multiple TTS Engine Support**  \n  Compatible with VOICEVOX, VoicePeak, OpenAI TTS, xAI TTS, Unreal Speech,\n  ElevenLabs, Fish Audio, Cartesia, Inworld, Gradium, Gemini TTS, MiniMax,\n  AivisSpeech, Aivis Cloud, Web Speech API, and more\n- **Unified Interface**  \n  Single API for all supported TTS engines\n- **Emotion-Aware Synthesis**  \n  Automatically detects and applies emotions from text tags like `[happy]`, `[sad]`, etc.\n- **Screenplay Conversion**  \n  Transforms text with emotion tags into structured screenplay format\n- **Browser Audio Support**  \n  Direct playback in web browsers using HTMLAudioElement\n- **Custom Endpoints**  \n  Support for self-hosted TTS servers\n- **Language Detection**  \n  Automatic language recognition for multi-language engines\n- **Flexible Configuration**  \n  Runtime engine switching and parameter updates\n\n## Basic Usage\n\n### Simple Text-to-Speech\n\n```typescript\nimport { VoiceService, VoiceServiceOptions } from '@aituber-onair/voice';\n\n// Configure the voice service\nconst options: VoiceServiceOptions = {\n  engineType: 'voicevox',\n  speaker: '1',\n  // Optional: specify custom endpoint\n  voicevoxApiUrl: 'http://localhost:50021'\n};\n\n// Create voice service instance\nconst voiceService = new VoiceService(options);\n\n// Speak text\nawait voiceService.speak({ text: 'Hello, world!' });\n```\n\n### Using VoiceEngineAdapter (Recommended)\n\n```typescript\nimport { VoiceEngineAdapter, VoiceServiceOptions } from '@aituber-onair/voice';\n\nconst options: VoiceServiceOptions = {\n  engineType: 'openai',\n  speaker: 'alloy',\n  apiKey: 'your-openai-api-key',\n  onPlay: async (audioBuffer) => {\n    // Custom audio playback handler\n    console.log('Playing audio...');\n  }\n};\n\nconst voiceAdapter = new VoiceEngineAdapter(options);\n\n// Speak with emotion\nawait voiceAdapter.speak({ \n  text: '[happy] I am so excited to talk with you!' \n});\n```\n\n## Supported TTS Engines\n\n### VOICEVOX\nHigh-quality Japanese speech synthesis engine with multiple character voices.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'voicevox',\n  speaker: '1', // Character ID\n  voicevoxApiUrl: 'http://localhost:50021' // Optional custom endpoint\n});\n```\n\n### VoicePeak\nProfessional speech synthesis with rich emotional expression.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'voicepeak',\n  speaker: 'f1',\n  voicepeakApiUrl: 'http://localhost:20202',\n  voicepeakEmotion: 'happy',\n  voicepeakSpeed: 140,\n  voicepeakPitch: 20\n});\n```\n\nSingle-tag `voicepeakEmotion` remains backward compatible with existing\nVoicePeak setups. Weighted emotion maps require `vpeakserver >= v0.2.0`.\n\n```typescript\nconst weightedVoiceService = new VoiceService({\n  engineType: 'voicepeak',\n  speaker: 'f1',\n  voicepeakApiUrl: 'http://localhost:20202',\n  voicepeakEmotion: { happy: 40, fun: 60 },\n});\n```\n\n- `neutral` is ignored when sending weighted emotions.\n- Weight `0` is ignored.\n- `{}` means \"do not send emotion\" and does not fall back to `Talk.style`.\n- `undefined` means no override, so `Talk.style` still maps to a single tag.\n\n### OpenAI TTS\nOpenAI's text-to-speech API with multiple voice options.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'openai',\n  speaker: 'alloy',\n  apiKey: 'your-openai-api-key'\n});\n```\n\n### xAI TTS\nxAI's cloud TTS API with selectable voice IDs, language control, and output\nformat tuning.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'xai',\n  speaker: 'eve',\n  apiKey: 'your-xai-api-key',\n  xaiLanguage: 'ja',\n  xaiCodec: 'mp3',\n  xaiSampleRate: 24000,\n  xaiBitRate: 128000,\n});\n```\n\n### Unreal Speech\nUnreal Speech v8 cloud TTS via the `/stream` endpoint. It returns audio bytes\ndirectly, so it works with `VoiceEngineAdapter` playback without an extra\ndownload step.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'unrealSpeech',\n  speaker: 'af_bella',\n  apiKey: 'your-unreal-speech-api-key',\n  unrealSpeechBitrate: '192k',\n  unrealSpeechSpeed: 0,\n  unrealSpeechPitch: 1,\n  unrealSpeechCodec: 'libmp3lame',\n  unrealSpeechTemperature: 0.25,\n});\n```\n\nUse `unrealSpeechApiUrl` to override the default\n`https://api.v8.unrealspeech.com/stream` endpoint.\n\n### ElevenLabs\nElevenLabs Text to Speech API support using direct `fetch` calls. No SDK is\nrequired.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'elevenLabs',\n  speaker: 'JBFqnCBsd6RMkjVDRZzb',\n  apiKey: 'your-elevenlabs-api-key',\n  elevenLabsModel: 'eleven_flash_v2_5',\n  elevenLabsOutputFormat: 'mp3_44100_128',\n  elevenLabsStability: 0.5,\n  elevenLabsSimilarityBoost: 0.75,\n  elevenLabsUseSpeakerBoost: true,\n});\n```\n\nUse `elevenLabsApiUrl` to override the default\n`https://api.elevenlabs.io/v1/text-to-speech` endpoint. The `speaker` value is\nsent as the ElevenLabs `voice_id`.\n\nThe curated model choices are `eleven_v3` for maximum expressiveness,\n`eleven_multilingual_v2` for high-quality multilingual output, and\n`eleven_flash_v2_5` (the default) for low latency. The deprecated\n`eleven_turbo_v2_5` remains accepted as a custom string for backward\ncompatibility, but is no longer presented as a recommended model.\n\n### Fish Audio\n\nFish Audio one-shot TTS uses `POST /v1/tts` and returns audio bytes directly.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'fishAudio',\n  speaker: 'your-reference-id',\n  apiKey: 'your-fish-audio-api-key',\n  fishAudioModel: 's2-pro',\n  fishAudioFormat: 'mp3',\n  fishAudioLatency: 'normal',\n});\n```\n\n`speaker` is sent as `reference_id`. Use `getVoiceEngineVoiceList('fishAudio',\n{ apiKey })` to list usable models/voices. `s2-pro` is the stable default for\nthis integration; `s2.1-pro-free` must be selected explicitly and should not be\ntreated as an SLA-backed production tier.\n\nVoice-list lookups return at most 100 entries by default so they do not traverse\nthe full public model catalog. Pass `limit` and optionally `pageSize` to request\na larger bounded result set.\n\nThe official `POST /v1/tts` endpoint does not currently complete browser CORS\npreflight requests. Call it directly from Node.js or a server, or set\n`fishAudioApiUrl` to a same-origin backend route in browser applications. Keep\nthe Fish Audio API key on the server in production. The React example includes\na Vite-only development/preview proxy for this purpose.\n\n### Cartesia\n\nCartesia synchronous TTS uses `POST /tts/bytes` and returns audio bytes\ndirectly.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'cartesia',\n  speaker: 'your-cartesia-voice-id',\n  apiKey: 'your-cartesia-api-key',\n  cartesiaModel: 'sonic-3.5',\n  cartesiaLanguage: 'ja',\n  cartesiaOutputContainer: 'wav',\n  cartesiaSampleRate: 44100,\n});\n```\n\nUse `getVoiceEngineVoiceList('cartesia', { apiKey, language: 'ja' })` to list\nvoices. The engine uses the documented `Cartesia-Version: 2026-03-01` header.\n\n### Inworld\nInworld TTS non-streaming speech synthesis using direct `fetch` calls. This\nengine uses the REST endpoint only; WebSocket and HTTP streaming are not\nimplemented.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'inworld',\n  speaker: 'Ashley',\n  apiKey: process.env.INWORLD_API_KEY,\n  inworldModel: 'inworld-tts-2',\n  inworldAudioEncoding: 'MP3',\n  inworldSampleRateHertz: 48000,\n});\n```\n\nUse `inworldApiUrl` to override the default\n`https://api.inworld.ai/tts/v1/voice` endpoint. The `apiKey` value should be\nthe Inworld Basic Base64 authorization value. Do not expose Basic credentials\nin browser-side code; use a backend proxy or Inworld JWT authentication for\nbrowser apps.\n\nThe current TTS-2 models are `inworld-tts-2` (the default, for quality)\nand `inworld-tts-2-flash` (an explicit option for lower latency and cost).\nSet `inworldModel: 'inworld-tts-2-flash'` to use Flash, or switch at runtime\nwith `voiceService.updateOptions({ inworldModel: 'inworld-tts-2-flash' })`.\nBoth use the same REST endpoint and voice-list configuration. This engine\nwaits for the complete audio response, so provider streaming latency figures\ndo not describe its playback latency.\n\n`inworldDeliveryMode` is supported only by TTS-2 and is omitted for Flash.\nEarlier model IDs remain accepted as strings for compatibility, but deprecated\nTTS 1.5 models are no longer offered in the React model selector.\nSee the [model catalog](https://docs.inworld.ai/tts/tts-models) and\n[speech API reference](https://docs.inworld.ai/api-reference/ttsAPI/texttospeech/synthesize-speech).\n\n### Gradium\nGradium one-shot REST TTS support using direct `fetch` calls. This engine uses\nthe raw-audio response mode (`only_audio: true`) and does not add the Gradium\nSDK.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'gradium',\n  speaker: 'YTpq7expH9539ERJ',\n  apiKey: process.env.GRADIUM_API_KEY,\n  gradiumOutputFormat: 'wav',\n  gradiumTemperature: 0.7,\n  gradiumVoiceSimilarity: 2,\n  gradiumPaddingBonus: 0,\n  gradiumRewriteRules: 'en',\n});\n```\n\nUse `gradiumApiUrl` to override the default\n`https://api.gradium.ai/api/post/speech/tts` endpoint. The `speaker` value is\nsent as Gradium `voice_id`. The React example uses Gradium flagship voice\npresets as a fallback and can fetch the Gradium voice list through\n`getVoiceEngineVoiceList()` when an API key is provided. Browser-side voice\nlist requests may fail if the Gradium API does not allow direct CORS access;\nuse a backend proxy for production browser UIs that need dynamic Gradium voice\nselection.\n\n### OpenAI-Compatible TTS\nOpenAI-compatible speech endpoints for self-hosted servers such as Kokoro FastAPI.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'openaiCompatible',\n  openAiCompatibleApiUrl: 'http://localhost:8880/v1/audio/speech',\n  openAiCompatibleModel: 'your-model-id'\n});\n```\n\n`speaker` is optional for compatible endpoints. When omitted, the request body\ndoes not include a `voice` field.\n`openAiCompatibleModel` should be set explicitly to a model name accepted by\nyour endpoint.\n\n### MiniMax\nMulti-language TTS supporting 24 languages with HD quality.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'minimax',\n  speaker: 'Japanese_IntellectualSenior',\n  apiKey: 'your-minimax-api-key',\n  minimaxModel: 'speech-2.8-turbo',\n  groupId: 'legacy-group-id', // Optional for older accounts\n  endpoint: 'global' // or 'china'\n});\n```\n\n**Note**: Current MiniMax T2A v2 endpoints require Bearer authentication but\ndo not require `GroupId`. The optional `groupId` field is kept for older\naccounts or endpoints that still expect the query parameter. Speech 2.8 Turbo\nis the default; Speech 2.8 HD is available when output quality is preferred.\n\nUse MiniMax system voice IDs for `speaker`, such as\n`Japanese_IntellectualSenior`. MiniMax documents these IDs in its\n[System Voice ID List](https://platform.minimax.io/docs/faq/system-voice-id).\nThe linked dynamic Get Voice API is not currently available, so\n`getVoiceEngineVoiceList()` does not expose MiniMax voice-list fetching.\n\n### AivisSpeech\nAI-powered speech synthesis with natural voice quality.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'aivisSpeech',\n  speaker: '888753760',\n  aivisSpeechApiUrl: 'http://localhost:10101'\n});\n```\n\n### Aivis Cloud\n\nHigh-quality cloud-based TTS service with advanced SSML support and streaming capabilities.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'aivisCloud',\n  speaker: 'unused', // Not used when model UUID is specified\n  apiKey: 'your-aivis-cloud-api-key',\n  aivisCloudModelUuid: 'a59cb814-0083-4369-8542-f51a29e72af7', // Required\n  \n  // Optional advanced settings\n  aivisCloudSpeakerUuid: 'speaker-uuid', // For multi-speaker models\n  aivisCloudStyleId: 0, // Or use aivisCloudStyleName: 'ノーマル'\n  aivisCloudUseSSML: true, // Enable SSML tags\n  aivisCloudSpeakingRate: 1.0, // 0.5-2.0\n  aivisCloudEmotionalIntensity: 1.0, // 0.0-2.0\n  aivisCloudOutputFormat: 'mp3', // wav, flac, mp3, aac, opus\n  aivisCloudOutputSamplingRate: 44100, // Hz\n});\n```\n\n**Key Features**:\n- **SSML Support**: Rich markup for prosody, breaks, aliases, and emotions\n- **Streaming Audio**: Real-time audio generation and delivery  \n- **Multiple Formats**: WAV, FLAC, MP3, AAC, Opus output\n- **Emotion Control**: Fine-grained emotional intensity settings\n- **High Quality**: Professional-grade voice synthesis\n\n`getVoiceEngineVoiceList('aivisCloud')` uses the Aivis Cloud model search API\n(`GET https://api.aivis-project.com/v1/aivm-models/search`) and returns model\nUUID choices that can be passed as `speaker` or `aivisCloudModelUuid`. Direct\nbrowser requests to model/list endpoints can fail CORS checks, so browser apps\nshould call this helper from a Node.js backend or relay/proxy when they need\ndynamic model, speaker, or style selection. The React example intentionally\nkeeps manual model UUID input instead of calling the model search endpoint from\nthe browser.\n\n### Gemini TTS\nGemini API text-to-speech with Gemini preview TTS models, including\n`gemini-3.1-flash-tts-preview`, and simple API key authentication.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'geminiTts',\n  speaker: 'Zephyr',\n  apiKey: 'your-google-api-key',\n  geminiTtsModel: 'gemini-3.1-flash-tts-preview',\n  geminiTtsLanguageCode: 'ja-JP',\n  geminiTtsPrompt: 'Speak in a cheerful tone', // Optional style or audio-tag instruction\n  geminiTtsApiUrl:\n    'https://generativelanguage.googleapis.com/v1beta', // Optional Gemini API base URL\n});\n```\n\n**Note**: Use a standard Google API key. `apiKey` is sent as\n`x-goog-api-key` to the Gemini API. Available voices include Zephyr, Aoede,\nKore, Puck, Charon, and 25+ more prebuilt voices.\n\n### Web Speech API\nBrowser-native speech synthesis through `window.speechSynthesis`. This engine\ndoes not return audio bytes; the browser plays speech directly.\n\n```typescript\nconst voiceService = new VoiceEngineAdapter({\n  engineType: 'webSpeech',\n  speaker: '', // Optional: SpeechSynthesisVoice name or voiceURI\n  webSpeechLanguage: 'ja-JP',\n  webSpeechRate: 1.1,\n  webSpeechPitch: 1.0,\n  webSpeechVolume: 1.0,\n});\n\nawait voiceService.speak({ text: 'こんにちは' });\n```\n\nUse `getVoiceEngineVoiceList('webSpeech')` in a browser to list available\n`SpeechSynthesisVoice` entries. Some browsers populate voices asynchronously,\nso the helper waits briefly for `voiceschanged`. Because no `ArrayBuffer` is\navailable, `onPlay(audioBuffer)` is skipped for this engine; `onComplete` still\nruns when the utterance ends. Runtime support is browser-only.\n\n### None (Silent Mode)\nNo audio output - useful for testing or text-only scenarios.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'none'\n});\n```\n\n## Emotion-Aware Speech\n\nThe library supports emotion tags in text for more expressive speech:\n\n```typescript\n// Emotion tags are automatically detected and processed\nawait voiceService.speak({ \n  text: '[happy] Great to see you today!' \n});\n\nawait voiceService.speak({ \n  text: '[sad] I will miss you...' \n});\n\nawait voiceService.speak({ \n  text: '[angry] This is unacceptable!' \n});\n\n// Supported emotions vary by engine\n// Common emotions: happy, sad, angry, surprised, neutral\n```\n\nThe emotion system works by:\n1. Extracting emotion tags from the text\n2. Converting text to screenplay format with emotion metadata\n3. Passing emotion information to engines that support it\n4. Falling back gracefully for engines without emotion support\n\n## Browser Compatibility\n\nThe library includes built-in browser audio playback support:\n\n```typescript\n// Option 1: Default browser playback\nconst voiceService = new VoiceService({\n  engineType: 'openai',\n  speaker: 'alloy',\n  apiKey: 'your-api-key'\n  // Audio will play automatically in the browser\n});\n\n// Option 2: Custom audio handling\nconst voiceService = new VoiceService({\n  engineType: 'voicevox',\n  speaker: '1',\n  onPlay: async (audioBuffer: ArrayBuffer) => {\n    // Custom audio playback logic\n    const audioContext = new AudioContext();\n    const audioBufferSource = audioContext.createBufferSource();\n    // ... handle audio playback\n  }\n});\n\n// Option 3: Specify HTML audio element\nconst voiceService = new VoiceService({\n  engineType: 'voicevox',\n  speaker: '1',\n  voicevoxApiUrl: 'http://localhost:50021',\n  audioElementId: 'my-audio-player' // ID of <audio> element\n});\n```\n\n## Advanced Configuration\n\n### Dynamic Engine Switching\n\n```typescript\nconst voiceAdapter = new VoiceEngineAdapter({\n  engineType: 'voicevox',\n  speaker: '1'\n});\n\n// Update options within the same engine\nvoiceAdapter.updateOptions({\n  speaker: '3',\n  voicevoxSpeedScale: 1.1,\n});\n\n// Switch to a different engine at runtime\nvoiceAdapter.switchEngine({\n  engineType: 'openai',\n  speaker: 'nova',\n  apiKey: 'your-openai-api-key'\n});\n\n// Backward compatibility:\n// updateOptions with engineType is still accepted.\nvoiceAdapter.updateOptions({\n  engineType: 'openai',\n  speaker: 'nova',\n  apiKey: 'your-openai-api-key'\n});\n```\n\n### Custom Endpoints\n\n```typescript\n// For self-hosted or custom TTS servers\nconst voiceService = new VoiceService({\n  engineType: 'voicevox',\n  speaker: '1',\n  voicevoxApiUrl: 'https://my-custom-voicevox-server.com'\n});\n```\n\n### Engine Parameter Overrides\n\n`VoiceServiceOptions` (see [API Reference](#voiceserviceoptions)) now covers a consistent set of overrides for each engine. Below is a field-by-field summary to help you discover the right property without scanning the entire interface.\n\n```typescript\nconst voiceService = new VoiceService({\n  engineType: 'voicevox',\n  speaker: '1',\n  openAiSpeed: 1.15,\n  openAiCompatibleModel: 'your-model-id',\n  openAiCompatibleSpeed: 1.1,\n  openAiCompatibleTimeoutMs: 300_000, // Optional; default: 30_000 ms; 0 disables the timeout\n  unrealSpeechBitrate: '192k',\n  unrealSpeechSpeed: 0,\n  unrealSpeechPitch: 1,\n  elevenLabsModel: 'eleven_flash_v2_5',\n  elevenLabsStability: 0.5,\n  elevenLabsSimilarityBoost: 0.75,\n  inworldModel: 'inworld-tts-2',\n  inworldAudioEncoding: 'MP3',\n  inworldSampleRateHertz: 48000,\n  gradiumOutputFormat: 'wav',\n  gradiumTemperature: 0.7,\n  gradiumVoiceSimilarity: 2,\n  voicevoxSpeedScale: 1.1,\n  voicevoxPitchScale: 0.05,\n  voicevoxIntonationScale: 1.2,\n  voicevoxQueryParameters: { pauseLength: 0.3, outputSamplingRate: 44100 },\n  minimaxVoiceSettings: { speed: 1.05, vol: 1.1, pitch: 2 },\n  minimaxAudioSettings: { sampleRate: 44100, format: 'mp3' },\n  aivisSpeechSpeedScale: 1.05,\n  aivisCloudSpeakingRate: 1.1,\n  aivisCloudVolume: 1.05,\n});\n```\n\n> Tip: the React example in `packages/voice/examples/react-basic` exposes the same controls with collapsible cards + sliders, making it easy to try values before applying them in code.\n\n#### Engine parameter reference\n\n- **OpenAI TTS**\n  - `openAiModel`\n  - `openAiSpeed`\n\n- **OpenAI-Compatible TTS**\n  - Endpoint: `openAiCompatibleApiUrl`\n  - Optional voice: `speaker`\n  - `openAiCompatibleModel`\n  - `openAiCompatibleSpeed`\n  - `openAiCompatibleTimeoutMs`\n\n- **xAI TTS**\n  - `xaiLanguage`\n  - `xaiCodec`\n  - `xaiSampleRate`\n  - `xaiBitRate`\n\n- **Unreal Speech**\n  - Endpoint: `unrealSpeechApiUrl`\n  - Output: `unrealSpeechBitrate`, `unrealSpeechCodec`\n  - Voice controls: `unrealSpeechSpeed`, `unrealSpeechPitch`, `unrealSpeechTemperature`\n\n- **ElevenLabs**\n  - Endpoint: `elevenLabsApiUrl`\n  - Identity/output: `speaker`, `elevenLabsModel`, `elevenLabsOutputFormat`, `elevenLabsLanguageCode`\n  - Voice settings: `elevenLabsVoiceSettings`, `elevenLabsStability`, `elevenLabsSimilarityBoost`, `elevenLabsStyle`, `elevenLabsUseSpeakerBoost`, `elevenLabsSpeed`\n  - Context/normalization: `elevenLabsSeed`, `elevenLabsPreviousText`, `elevenLabsNextText`, `elevenLabsApplyTextNormalization`, `elevenLabsApplyLanguageTextNormalization`, `elevenLabsEnableLogging`\n\n- **Fish Audio**\n  - Endpoint: `fishAudioApiUrl`\n  - Identity/output: `speaker`, `fishAudioModel`, `fishAudioFormat`, `fishAudioSampleRate`, `fishAudioMp3Bitrate`\n  - Voice controls: `fishAudioLatency`, `fishAudioSpeed`\n\n- **Cartesia**\n  - Endpoint: `cartesiaApiUrl`\n  - Identity/output: `speaker`, `cartesiaModel`, `cartesiaLanguage`, `cartesiaOutputContainer`, `cartesiaSampleRate`, `cartesiaMp3Bitrate`\n\n- **Inworld**\n  - Endpoint: `inworldApiUrl`\n  - Identity/output: `speaker`, `inworldModel`, `inworldAudioEncoding`, `inworldSampleRateHertz`, `inworldBitRate`\n  - Voice controls: `inworldSpeakingRate`, `inworldLanguage`, `inworldDeliveryMode`, `inworldTemperature`\n\n- **Gradium**\n  - Endpoint: `gradiumApiUrl`\n  - Identity/output: `speaker`, `gradiumOutputFormat`\n  - Voice controls: `gradiumTemperature`, `gradiumVoiceSimilarity`, `gradiumPaddingBonus`, `gradiumRewriteRules`\n\n- **VOICEVOX**\n  - Endpoint: `voicevoxApiUrl`\n  - Scalars: `voicevoxSpeedScale`, `voicevoxPitchScale`, `voicevoxIntonationScale`, `voicevoxVolumeScale`\n  - Timing: `voicevoxPrePhonemeLength`, `voicevoxPostPhonemeLength`, `voicevoxPauseLength`, `voicevoxPauseLengthScale`\n  - Output: `voicevoxOutputSamplingRate`, `voicevoxOutputStereo`\n  - Flags: `voicevoxEnableKatakanaEnglish`, `voicevoxEnableInterrogativeUpspeak`\n  - Version: `voicevoxCoreVersion`\n  - Low-level overrides: `voicevoxQueryParameters`\n\n- **AivisSpeech**\n  - Endpoint: `aivisSpeechApiUrl`\n  - Scalars: `aivisSpeechSpeedScale`, `aivisSpeechPitchScale`, `aivisSpeechIntonationScale`, `aivisSpeechTempoDynamicsScale`, `aivisSpeechVolumeScale`\n  - Timing: `aivisSpeechPrePhonemeLength`, `aivisSpeechPostPhonemeLength`, `aivisSpeechPauseLength`, `aivisSpeechPauseLengthScale`\n  - Output: `aivisSpeechOutputSamplingRate`, `aivisSpeechOutputStereo`\n  - Low-level overrides: `aivisSpeechQueryParameters`\n\n- **Aivis Cloud**\n  - Identity: `aivisCloudModelUuid`, `aivisCloudSpeakerUuid`, `aivisCloudStyleId`, `aivisCloudStyleName`, `aivisCloudUserDictionaryUuid`\n  - Behaviour: `aivisCloudUseSSML`, `aivisCloudLanguage`, `aivisCloudSpeakingRate`, `aivisCloudEmotionalIntensity`, `aivisCloudTempoDynamics`, `aivisCloudPitch`, `aivisCloudVolume`\n  - Silence: `aivisCloudLeadingSilence`, `aivisCloudTrailingSilence`, `aivisCloudLineBreakSilence`\n  - Output: `aivisCloudOutputFormat`, `aivisCloudOutputBitrate`, `aivisCloudOutputSamplingRate`, `aivisCloudOutputChannels`\n  - Logging: `aivisCloudEnableBillingLogs`\n\n- **VoicePeak**\n  - Endpoint: `voicepeakApiUrl`\n  - Emotion: `voicepeakEmotion` (single tag or weighted map)\n  - Scalars: `voicepeakSpeed`, `voicepeakPitch`\n\n- **MiniMax**\n  - Identity: `groupId`, `endpoint`, `minimaxModel`, `minimaxLanguageBoost`\n  - Voice overrides: `minimaxVoiceSettings` or individual `minimaxSpeed`, `minimaxVolume`, `minimaxPitch`\n  - Audio overrides: `minimaxAudioSettings` or individual `minimaxSampleRate`, `minimaxBitrate`, `minimaxAudioFormat`, `minimaxAudioChannel`\n\n### Error Handling\n\n```typescript\ntry {\n  await voiceService.speak({ text: 'Hello!' });\n} catch (error) {\n  if (error.message.includes('API key')) {\n    console.error('Invalid API key');\n  } else if (error.message.includes('network')) {\n    console.error('Network error - check your connection');\n  } else {\n    console.error('TTS error:', error);\n  }\n}\n```\n\n## Engine-Specific Features\n\n### VOICEVOX Features\n- Multiple character voices with unique personalities\n- Adjustable speech parameters (speed, pitch, intonation)\n- Local server support for privacy\n\n### OpenAI TTS Features\n- High-quality multilingual support\n- Multiple voice personalities\n- Optimized for conversational AI\n\n### xAI TTS Features\n- Cloud TTS endpoint with Bearer token authentication\n- Passes `speaker` through to `voice_id` as provided\n- Configurable codec, sample rate, and MP3 bitrate\n\n### Unreal Speech Features\n- Cloud TTS endpoint with Bearer token authentication\n- Passes `speaker` through to `VoiceId` as provided\n- Configurable bitrate, codec, speed, pitch, and temperature\n- Uses the v8 `/stream` API, which returns audio bytes directly\n\n### ElevenLabs Features\n- Cloud TTS endpoint with `xi-api-key` authentication\n- Passes `speaker` through to `voice_id` as provided\n- Configurable model, output format, language code, and voice settings\n- Supports optional text context, seed, text normalization, and logging flags\n\n### Fish Audio Features\n\n- Bearer-authenticated one-shot TTS with direct audio-byte responses\n- Configurable S2/S1 model, format, sample rate, MP3 bitrate, latency, and speed\n- Paginated model/voice-list lookup through the normalized helper\n\n### Cartesia Features\n\n- Bearer-authenticated synchronous `/tts/bytes` requests\n- Sonic 3.5 with Japanese and other documented language codes\n- Paginated voice-list lookup and WAV/MP3 output controls\n\n### Inworld Features\n- Cloud TTS endpoint with Basic authentication\n- Passes `speaker` through to `voiceId` as provided\n- Configurable model, audio encoding, sample rate, bit rate, speaking rate, language, delivery mode, and temperature\n- Uses the non-streaming REST API and decodes the returned `audioContent`\n\n### Gradium Features\n- Cloud TTS endpoint with `x-api-key` authentication\n- Passes `speaker` through to `voice_id` as provided\n- Configurable output format and `json_config` controls for temperature, voice similarity, speed, and rewrite rules\n- Flagship voice presets provide readable names for browser speaker selectors\n- Dynamic voice-list lookups may require a backend proxy in browser apps if the provider blocks direct CORS access\n\n### MiniMax Features\n- 24 language support with automatic detection\n- HD quality audio output\n- Dual-region endpoints (global/china)\n- Advanced emotion synthesis\n- Uses documented system voice IDs instead of dynamic voice-list fetching\n\n### Gemini TTS Features\n- Gemini API-based high-quality voice synthesis\n- 30+ voice options (star/moon themed names)\n- Prompt-based style/tone control\n- Simple API key authentication with `x-goog-api-key`\n- Configurable Gemini API base URL\n- 24+ language support including Japanese\n\n### Web Speech API Features\n- Browser-native `speechSynthesis` playback with no API key\n- Browser-only runtime; no Node.js or server audio byte output\n- Supports voice selection by `SpeechSynthesisVoice.name` or `voiceURI`\n- Supports rate, pitch, volume, and language options where the browser voice honors them\n\n## Integration with AITuber OnAir Core\n\nWhile this package can be used independently, it integrates seamlessly with [@aituber-onair/core](https://www.npmjs.com/package/@aituber-onair/core):\n\n```typescript\nimport { AITuberOnAirCore } from '@aituber-onair/core';\n\nconst core = new AITuberOnAirCore({\n  apiKey: 'your-openai-key',\n  voiceOptions: {\n    engineType: 'voicevox',\n    speaker: '1',\n    voicevoxApiUrl: 'http://localhost:50021'\n  }\n});\n\n// Voice synthesis is handled automatically\nawait core.processChat('Hello!');\n```\n\n## API Reference\n\n### VoiceServiceOptions\n\n```typescript\ntype VoiceServiceOptions =\n  | VoiceVoxVoiceServiceOptions\n  | VoicePeakVoiceServiceOptions\n  | OpenAiVoiceServiceOptions\n  | XaiVoiceServiceOptions\n  | UnrealSpeechVoiceServiceOptions\n  | ElevenLabsVoiceServiceOptions\n  | FishAudioVoiceServiceOptions\n  | CartesiaVoiceServiceOptions\n  | InworldVoiceServiceOptions\n  | GradiumVoiceServiceOptions\n  | GeminiTtsVoiceServiceOptions\n  | OpenAiCompatibleVoiceServiceOptions\n  | AivisSpeechVoiceServiceOptions\n  | AivisCloudVoiceServiceOptions\n  | MinimaxVoiceServiceOptions\n  | PiperPlusVoiceServiceOptions\n  | WebSpeechVoiceServiceOptions\n  | NoneVoiceServiceOptions;\n```\n\n`VoiceServiceOptions` is a discriminated union keyed by `engineType`.\nUse `updateOptions(...)` for same-engine updates and `switchEngine(...)`\nfor cross-engine changes.\nFor backward compatibility, cross-engine fields in `updateOptions(...)`\nare still accepted.\n\n### Engine Capabilities\n\n```typescript\nimport {\n  getAllVoiceEngineCapabilities,\n  getVoiceEngineCapabilities,\n} from '@aituber-onair/voice';\n\nconst gradium = getVoiceEngineCapabilities('gradium');\nconsole.log(gradium.supportsVoiceList); // true\n\nconst allEngines = getAllVoiceEngineCapabilities();\n```\n\nCapabilities are static metadata only. They do not include API keys,\nendpoints, user configuration, or other sensitive values.\n\n### Voice Lists\n\n```typescript\nimport { getVoiceEngineVoiceList } from '@aituber-onair/voice';\n\nconst voices = await getVoiceEngineVoiceList('elevenLabs', {\n  apiKey: process.env.ELEVENLABS_API_KEY,\n});\n\n// [{ id: '...', label: 'Rachel (premade)' }, ...]\n```\n\n`getVoiceEngineVoiceList()` returns normalized `{ id, label }` items for\nengines that expose list APIs: VOICEVOX, AivisSpeech, Aivis Cloud, xAI,\nElevenLabs, Fish Audio, Cartesia, Inworld, Gradium, and Web Speech API. Pass\nlocal `apiUrl` for VOICEVOX-compatible servers, `apiKey` for cloud engines that\nrequire it, and `language` for Fish Audio, Cartesia, or Inworld filtering.\n\nFor browser apps, cloud provider voice-list endpoints must allow CORS. If a\nprovider blocks direct browser requests, call `getVoiceEngineVoiceList()` from\nyour backend or expose a small backend relay/proxy for the list endpoint.\n\nAivis Cloud voice-list support is package-level support for the model search\nendpoint. Browser requests to Aivis Cloud model/list endpoints can be blocked\nby CORS; call the helper from Node.js/backend or expose a backend proxy before\nwiring dynamic Aivis Cloud model selection into a production UI.\n\nMiniMax is also excluded from this helper. Use the documented system voice IDs\ndirectly because the linked dynamic Get Voice API is currently unavailable.\n\n### VoiceService Methods\n\n```typescript\ninterface VoiceService {\n  speak(screenplay: ChatScreenplay, options?: AudioPlayOptions): Promise<void>;\n  speakText(text: string, options?: AudioPlayOptions): Promise<void>;\n  isPlaying(): boolean;\n  stop(): void;\n  updateOptions(\n    options: VoiceServiceOptionsUpdate | Partial<VoiceServiceOptions>\n  ): void;\n  switchEngine?(options: VoiceServiceOptions): void;\n}\n```\n\n### Screenplay Format\n\n```typescript\ninterface Screenplay {\n  emotion?: string;\n  text: string;\n  speechText?: string;\n}\n```\n\n## Examples\n\n### React Integration\n\nSee the [React example](./examples/react-basic) for a complete implementation:\n\n```typescript\nimport { useState } from 'react';\nimport { VoiceService } from '@aituber-onair/voice';\n\nfunction VoiceDemo() {\n  const [voiceService] = useState(\n    () => new VoiceService({\n      engineType: 'openai',\n      speaker: 'alloy',\n      apiKey: 'your-api-key'\n    })\n  );\n\n  const handleSpeak = async (text: string) => {\n    await voiceService.speak({ text });\n  };\n\n  return (\n    <button onClick={() => handleSpeak('[happy] Hello!')}>\n      Speak with emotion\n    </button>\n  );\n}\n```\n\n### Node.js Usage\n\nThe voice package now fully supports Node.js environments with automatic environment detection:\n\n```typescript\nimport { VoiceEngineAdapter } from '@aituber-onair/voice';\n\nconst voiceService = new VoiceEngineAdapter({\n  engineType: 'openai',\n  speaker: 'nova',\n  apiKey: process.env.OPENAI_API_KEY\n});\n\n// Audio will be played using available Node.js audio libraries\nawait voiceService.speak({ text: 'Hello from Node.js!' });\n```\n\n#### Audio Playback in Node.js\n\nFor audio playback in Node.js, install one of these optional dependencies:\n\n```bash\n# Option 1: speaker (native bindings, better quality)\nnpm install speaker\n\n# Option 2: play-sound (uses system audio player, easier to install)\nnpm install play-sound\n```\n\nIf neither is installed, the package will still work but won't play audio. You can still use the `onPlay` callback to handle audio data:\n\n```typescript\nconst voiceService = new VoiceEngineAdapter({\n  engineType: 'voicevox',\n  speaker: '1',\n  voicevoxApiUrl: 'http://localhost:50021',\n  onPlay: async (audioBuffer) => {\n    // Save to file or process audio data\n    writeFileSync('output.wav', Buffer.from(audioBuffer));\n  }\n});\n```\n\nThe package automatically detects the environment and uses the appropriate audio player:\n- **Browser**: Uses HTMLAudioElement\n- **Node.js**: Uses speaker or play-sound if available, otherwise silent\n\n## Testing\n\nRun the test suite:\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Generate coverage report\nnpm run test:coverage\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n","readmeFilename":"README.md"}