You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
voicebot/tts/ttsselvas.go

124 lines
2.8 KiB
Go

//for SELVAS streaming TTS
package tts
/*
#cgo LDFLAGS: ./extlib/selvastts/lib/Linux/C/x64/libpttsnet_m.a
#cgo CFLAGS: -I ../extlib/selvastts/include
#include <stdio.h>
#include <stdlib.h>
#include <pttsnet.h>
#include <pserrno.h>
*/
import "C"
import (
"unsafe"
"gitlab.com/cinnamon/voiceagent/icserror"
)
const (
DEFAULT_STTS_PITCH = -1
DEFAULT_STTS_SPEED = -1
DEFAULT_STTS_VOLUME = -1
DEFAULT_STTS_LANGUAGE = 0
DEFAULT_STTS_SPEAKER = 8
FRAMESIZE = 32000
CONNECTION_TIMEOUT = 3
READWRITE_TIMEOUT = 5
)
//for selvas tts
type STTS struct {
handle int
ch int
text string
pitch int
vol int
speed int
}
func NewSTTS(IP, port, text string) (*STTS, *icserror.IcsError) {
if len(IP) <= 0 || len(port) <= 0 {
return nil, icserror.ICSERRInvalidParam
}
stts := STTS{handle: -1, text: text, pitch: DEFAULT_STTS_PITCH, vol: DEFAULT_STTS_VOLUME, speed: DEFAULT_STTS_SPEED}
csIP := C.CString(IP)
csPort := C.CString(port)
rc := C.PTTSNET_INIT(DEFAULT_STTS_LANGUAGE, DEFAULT_STTS_SPEAKER, csIP, csPort, CONNECTION_TIMEOUT, READWRITE_TIMEOUT)
if int(rc) < 0 {
C.free(unsafe.Pointer(csIP))
C.free(unsafe.Pointer(csPort))
return nil, icserror.ICSERRTTSFailInit
}
stts.handle = int(rc)
//fmt.Println("Inited STTS :", rc, stts.handle)
csText := C.CString(text)
//fmt.Println("open", time.Now())
chrc := C.PTTSNET_OPEN(C.int(stts.handle), csText, C.PTTSNET_FMT8K_16BIT_PCM, DEFAULT_STTS_PITCH, DEFAULT_STTS_SPEED, DEFAULT_STTS_VOLUME, 0, C.PTTSNET_CONTENT_PLAIN, C.PTTSNET_CHARSET_UTF8)
if int(chrc) < 0 {
//fmt.Println("failed open tts")
C.free(unsafe.Pointer(csIP))
C.free(unsafe.Pointer(csPort))
C.free(unsafe.Pointer(csText))
return nil, icserror.ICSERRTTSFailInit
}
stts.ch = int(chrc)
//fmt.Println("TTS opened :", stts.ch)
C.free(unsafe.Pointer(csIP))
C.free(unsafe.Pointer(csPort))
C.free(unsafe.Pointer(csText))
return &stts, nil
}
func (s *STTS) Close() *icserror.IcsError {
if s.handle < 0 || s.ch < 0 {
return icserror.ICSERRTTSNotInit
}
rc := C.PTTSNET_CLOSE(C.int(s.ch), nil)
if int(rc) != 0 {
return icserror.ICSERRTTSFail
}
//fmt.Println(rc)
//fmt.Println("close", time.Now())
rc = C.PTTSNET_EXIT(C.int(s.handle))
if int(rc) != 0 {
return icserror.ICSERRTTSFail
}
//fmt.Println(rc)
s.text = ""
s.handle = -1
s.ch = -1
return nil
}
func (s *STTS) Read() ([]byte, int, *icserror.IcsError) {
if s.handle < 0 || s.ch < 0 {
return nil, -1, icserror.ICSERRTTSNotInit
}
frameBuf := make([]byte, FRAMESIZE)
nSize := C.PTTSNET_READ(C.int(s.ch), (*C.char)(unsafe.Pointer(&frameBuf[0])), FRAMESIZE)
if int(nSize) < 0 {
//fmt.Println("Failed to read TTS")
return nil, -1, icserror.ICSERRTTSFail
} else if int(nSize) == 0 {
return nil, -1, icserror.ICSERRTTSOK
}
//fmt.Println(nSize, time.Now())
return frameBuf, int(nSize), icserror.ICSERRTTSContinue
}