Add Go implementation of the TTS generation callback (#2213)

This commit is contained in:
愚者自愚
2025-05-14 16:09:31 +08:00
committed by GitHub
parent 0dfafed7d0
commit 116977b5d4
22 changed files with 364 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
*.wav
vits-ljs
vits-vctk
vits-zh-aishell3
offline-tts-play

View File

@@ -0,0 +1,10 @@
module offline-tts-play
go 1.17
replace github.com/k2-fsa/sherpa-onnx-go/sherpa_onnx => ../
require (
github.com/k2-fsa/sherpa-onnx-go/sherpa_onnx v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.6
)

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/main.go

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-kokoro-en.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-kokoro-zh-en.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-matcha-en.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-matcha-zh.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-vits-ljs.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-vits-piper-en_US-lessac-medium.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-vits-vctk.sh

View File

@@ -0,0 +1 @@
../../../../go-api-examples/non-streaming-tts/run-vits-zh-aishell3.sh

View File

@@ -41,8 +41,13 @@ package sherpa_onnx
// #include <stdlib.h>
// #include "c-api.h"
// extern int32_t _cgoGeneratedAudioCallback(float *samples,int32_t n,void *arg);
// extern int32_t _cgoGeneratedAudioProgressCallback(float *samples, int32_t n, float p, void *arg);
import "C"
import "unsafe"
import (
"runtime/cgo"
"unsafe"
)
// Configuration for online/streaming transducer models
//
@@ -890,6 +895,36 @@ type OfflineTts struct {
impl *C.struct_SherpaOnnxOfflineTts
}
type sherpaOnnxGeneratedAudioCallbackWithArg func(samples []float32)
//export _cgoGeneratedAudioCallback
func _cgoGeneratedAudioCallback(samples *C.float, n C.int32_t, arg unsafe.Pointer) C.int32_t {
h := *(*cgo.Handle)(arg)
val := h.Value().(sherpaOnnxGeneratedAudioCallbackWithArg)
all := make([]float32, n)
arr := unsafe.Slice(samples, n)
for i := 0; i < int(n); i++ {
all[i] = float32(arr[i])
}
val(all)
return 1
}
type sherpaOnnxGeneratedAudioProgressCallbackWithArg func(samples []float32, p float32)
//export _cgoGeneratedAudioProgressCallback
func _cgoGeneratedAudioProgressCallback(samples *C.float, n C.int32_t, p C.float, arg unsafe.Pointer) C.int32_t {
h := *(*cgo.Handle)(arg)
val := h.Value().(sherpaOnnxGeneratedAudioProgressCallbackWithArg)
all := make([]float32, n)
arr := unsafe.Slice(samples, n)
for i := 0; i < int(n); i++ {
all[i] = float32(arr[i])
}
val(all, float32(p))
return 1
}
// Free the internal pointer inside the tts to avoid memory leak.
func DeleteOfflineTts(tts *OfflineTts) {
C.SherpaOnnxDestroyOfflineTts(tts.impl)
@@ -1010,6 +1045,26 @@ func (tts *OfflineTts) Generate(text string, sid int, speed float32) *GeneratedA
return ans
}
func (tts *OfflineTts) GenerateWithCallback(text string, sid int, speed float32, cb sherpaOnnxGeneratedAudioCallbackWithArg) {
s := C.CString(text)
defer C.free(unsafe.Pointer(s))
h := cgo.NewHandle(cb)
defer h.Delete()
audio := C.SherpaOnnxOfflineTtsGenerateWithCallbackWithArg(tts.impl, s, C.int(sid), C.float(speed), C.SherpaOnnxGeneratedAudioCallbackWithArg(C._cgoGeneratedAudioCallback), unsafe.Pointer(&h))
defer C.SherpaOnnxDestroyOfflineTtsGeneratedAudio(audio)
}
func (tts *OfflineTts) GenerateWithProgressCallback(text string, sid int, speed float32, cb sherpaOnnxGeneratedAudioProgressCallbackWithArg) {
s := C.CString(text)
defer C.free(unsafe.Pointer(s))
h := cgo.NewHandle(cb)
defer h.Delete()
audio := C.SherpaOnnxOfflineTtsGenerateWithProgressCallbackWithArg(tts.impl, s, C.int(sid), C.float(speed), C.SherpaOnnxGeneratedAudioProgressCallbackWithArg(C._cgoGeneratedAudioProgressCallback), unsafe.Pointer(&h))
defer C.SherpaOnnxDestroyOfflineTtsGeneratedAudio(audio)
}
func (audio *GeneratedAudio) Save(filename string) bool {
s := C.CString(filename)
defer C.free(unsafe.Pointer(s))