@@ -28,7 +28,9 @@ function freeConfig(config, Module) {
2828 freeConfig ( config . pocket , Module )
2929 }
3030
31- Module . _free ( config . ptr ) ;
31+ if ( config . ptr ) {
32+ Module . _free ( config . ptr ) ;
33+ }
3234}
3335
3436// The user should free the returned pointers
@@ -620,9 +622,6 @@ function initSherpaOnnxGenerationConfig(config, Module) {
620622 const len = 9 * 4 ;
621623 const ptr = Module . _malloc ( len ) ;
622624
623- // Zero-init for safety
624- Module . HEAPU8 . fill ( 0 , ptr , ptr + len ) ;
625-
626625 // float silence_scale
627626 Module . setValue ( ptr + 0 * 4 , config . silenceScale || 0.2 , 'float' ) ;
628627
@@ -714,6 +713,8 @@ class OfflineTts {
714713 }
715714
716715 free ( ) {
716+ if ( ! this . handle ) return ;
717+
717718 this . Module . _SherpaOnnxDestroyOfflineTts ( this . handle ) ;
718719 this . handle = 0
719720 }
@@ -724,32 +725,47 @@ class OfflineTts {
724725 // speed: 1.0
725726 // }
726727 generate ( config ) {
728+ if ( ! this . handle ) {
729+ throw new Error ( 'OfflineTts has been freed' ) ;
730+ }
731+
732+ if ( ! config || ! config . text ) {
733+ throw new Error ( 'config.text is required' ) ;
734+ }
735+
727736 const textLen = this . Module . lengthBytesUTF8 ( config . text ) + 1 ;
728737 const textPtr = this . Module . _malloc ( textLen ) ;
729738 this . Module . stringToUTF8 ( config . text , textPtr , textLen ) ;
730739
731740 const h = this . Module . _SherpaOnnxOfflineTtsGenerate (
732- this . handle , textPtr , config . sid , config . speed ) ;
741+ this . handle , textPtr , config . sid ?? 0 , config . speed ?? 1.0 ) ;
742+
733743 this . Module . _free ( textPtr ) ;
734744
735745 if ( ! h ) {
736746 throw new Error ( 'TTS generation failed' ) ;
737747 }
738748
739- const numSamples = this . Module . HEAP32 [ h / 4 + 1 ] ;
740- const sampleRate = this . Module . HEAP32 [ h / 4 + 2 ] ;
749+ const base = h / 4 ;
741750
742- const samplesPtr = this . Module . HEAP32 [ h / 4 ] / 4 ;
743- const samples = new Float32Array ( numSamples ) ;
744- for ( let i = 0 ; i < numSamples ; i ++ ) {
745- samples [ i ] = this . Module . HEAPF32 [ samplesPtr + i ] ;
746- }
751+ const samplesPtr = this . Module . HEAPU32 [ base ] ;
752+ const numSamples = this . Module . HEAP32 [ base + 1 ] ;
753+ const sampleRate = this . Module . HEAP32 [ base + 2 ] ;
754+
755+ const heapSamples = this . Module . HEAPF32 . subarray (
756+ samplesPtr / 4 , samplesPtr / 4 + numSamples ) ;
757+
758+ const samples = new Float32Array ( heapSamples ) ;
747759
748760 this . Module . _SherpaOnnxDestroyOfflineTtsGeneratedAudio ( h ) ;
749761 return { samples : samples , sampleRate : sampleRate } ;
750762 }
751763
752764 generateWithConfig ( text , genConfig ) {
765+ if ( ! this . handle ) {
766+ throw new Error ( 'OfflineTts has been freed' ) ;
767+ }
768+
753769 const cfgWasm = initSherpaOnnxGenerationConfig ( genConfig , this . Module ) ;
754770
755771 const textLen = this . Module . lengthBytesUTF8 ( text ) + 1 ;
@@ -761,28 +777,24 @@ class OfflineTts {
761777 0 , // callback
762778 0 // callback arg
763779 ) ;
780+ this . Module . _free ( textPtr ) ;
781+ freeSherpaOnnxGenerationConfig ( cfgWasm , this . Module ) ;
764782
765783 if ( ! audioPtr ) {
766- this . Module . _free ( textPtr ) ;
767- freeSherpaOnnxGenerationConfig ( cfgWasm , this . Module ) ;
768784 throw new Error ( 'Failed to generate audio' ) ;
769785 }
770786
771- const samplesPtr = this . Module . HEAP32 [ audioPtr / 4 ] ; // float* samples
772- const numSamples =
773- this . Module . HEAP32 [ audioPtr / 4 + 1 ] ; // int32 num_samples
774- const sampleRate =
775- this . Module . HEAP32 [ audioPtr / 4 + 2 ] ; // int32 sample_rate
787+ const base = audioPtr / 4 ;
776788
777- // 5️⃣ Copy samples to Float32Array
778- const samples = new Float32Array ( numSamples ) ;
779- for ( let i = 0 ; i < numSamples ; i ++ ) {
780- samples [ i ] = this . Module . HEAPF32 [ samplesPtr / 4 + i ] ;
781- }
789+ const samplesPtr = this . Module . HEAPU32 [ base ] ; // float* samples
790+ const numSamples = this . Module . HEAP32 [ base + 1 ] ; // int32 num_samples
791+ const sampleRate = this . Module . HEAP32 [ base + 2 ] ; // int32 sample_rate
792+
793+ const heapSamples = this . Module . HEAPF32 . subarray (
794+ samplesPtr / 4 , samplesPtr / 4 + numSamples ) ;
795+ const samples = new Float32Array ( heapSamples ) ;
782796
783797 this . Module . _SherpaOnnxDestroyOfflineTtsGeneratedAudio ( audioPtr ) ;
784- this . Module . _free ( textPtr ) ;
785- freeSherpaOnnxGenerationConfig ( cfgWasm , this . Module ) ;
786798
787799 return { samples, sampleRate} ;
788800 }
@@ -791,9 +803,8 @@ class OfflineTts {
791803 const samples = audio . samples ;
792804 const sampleRate = audio . sampleRate ;
793805 const ptr = this . Module . _malloc ( samples . length * 4 ) ;
794- for ( let i = 0 ; i < samples . length ; i ++ ) {
795- this . Module . HEAPF32 [ ptr / 4 + i ] = samples [ i ] ;
796- }
806+
807+ this . Module . HEAPF32 . set ( samples , ptr / 4 ) ;
797808
798809 const filenameLen = this . Module . lengthBytesUTF8 ( filename ) + 1 ;
799810 const buffer = this . Module . _malloc ( filenameLen ) ;
0 commit comments