2025-01-16 18:33:47 +08:00
// Copyright (c) 2025 Xiaomi Corporation
const sherpa _onnx = require ( 'sherpa-onnx-node' ) ;
// please refer to
// https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/kokoro.html
// to download model files
function createOfflineTts ( ) {
const config = {
model : {
kokoro : {
model : './kokoro-en-v0_19/model.onnx' ,
voices : './kokoro-en-v0_19/voices.bin' ,
tokens : './kokoro-en-v0_19/tokens.txt' ,
dataDir : './kokoro-en-v0_19/espeak-ng-data' ,
} ,
debug : true ,
numThreads : 1 ,
provider : 'cpu' ,
} ,
maxNumSentences : 1 ,
} ;
return new sherpa _onnx . OfflineTts ( config ) ;
}
const tts = createOfflineTts ( ) ;
const text =
'Today as always, men fall into two groups: slaves and free men. Whoever does not have two-thirds of his day for himself, is a slave, whatever he may be: a statesman, a businessman, an official, or a scholar.'
let start = Date . now ( ) ;
const audio = tts . generate ( { text : text , sid : 6 , speed : 1.0 } ) ;
let stop = Date . now ( ) ;
const elapsed _seconds = ( stop - start ) / 1000 ;
const duration = audio . samples . length / audio . sampleRate ;
const real _time _factor = elapsed _seconds / duration ;
2025-02-17 12:24:52 +08:00
console . log ( 'Wave duration' , duration . toFixed ( 3 ) , 'seconds' )
console . log ( 'Elapsed' , elapsed _seconds . toFixed ( 3 ) , 'seconds' )
2025-01-16 18:33:47 +08:00
console . log (
` RTF = ${ elapsed _seconds . toFixed ( 3 ) } / ${ duration . toFixed ( 3 ) } = ` ,
real _time _factor . toFixed ( 3 ) )
const filename = 'test-kokoro-en-6.wav' ;
sherpa _onnx . writeWave (
filename , { samples : audio . samples , sampleRate : audio . sampleRate } ) ;
console . log ( ` Saved to ${ filename } ` ) ;