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.
728 lines
23 KiB
Go
728 lines
23 KiB
Go
//go:build !test
|
|
// +build !test
|
|
|
|
// for STT SELVAS STT
|
|
package stt
|
|
|
|
/*
|
|
#cgo LDFLAGS: -lstdc++ -ldl ./extlib/selvasstt/SDK/LIB/c_linux/x64/libASRLIB.a ./extlib/selvasstt/SDK/OpenSSL/Linux/Linux_x64/libssl.a ./extlib/selvasstt/SDK/OpenSSL/Linux/Linux_x64/libcrypto.a
|
|
#cgo CFLAGS: -I ../extlib/selvasstt/SDK/INCLUDE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <Lvcsr_Api.h>
|
|
|
|
char* getResultData(LVCSR_DATA_RESULT* pDataResult, long long nCount) {
|
|
char* skip1 = "<eps>";
|
|
char* space = " ";
|
|
int len = 0;
|
|
long long i;
|
|
|
|
for (i = 0; i < nCount; i++) {
|
|
len += strlen(pDataResult[i].pTokenStr) + 1;
|
|
printf("start: %ld, end: %ld\n", pDataResult[i].nStart, pDataResult[i].nEnd);
|
|
}
|
|
|
|
char* result = malloc(sizeof(char) * len);
|
|
strcpy(result, "");
|
|
|
|
for (i = 0; i < nCount; i++) {
|
|
if (strcmp(pDataResult[i].pTokenStr,skip1) == 0) {
|
|
} else {
|
|
strcat(result, space);
|
|
strcat(result, pDataResult[i].pTokenStr);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void freeResult(char* result){
|
|
if(result == NULL) {
|
|
return;
|
|
}
|
|
free(result);
|
|
}
|
|
|
|
int getMidResultEPD(LVCSR_RECOG_MID_RESULT *midResult){
|
|
return midResult->bEngineDetectionFlag;
|
|
}
|
|
|
|
void printMidResult(LVCSR_RECOG_MID_RESULT *midResult){
|
|
printf("result len : %ld\n", midResult->nResultLen);
|
|
printf("pResult : %s\n", midResult->pResult);
|
|
printf("flag : %d\n", midResult->bEngineDetectionFlag);
|
|
printf("count: %ld\n\n", midResult->nCount);
|
|
}
|
|
|
|
void setSid(LVCSR_DATA_LOGINFO *logInfo, char* sid, int size) {
|
|
// memset(logInfo.tloItemSId, 0, 51);
|
|
// memcpy(logInfo.tloItemSId, sid, size);
|
|
sprintf(logInfo->tloItemSId, "%s", sid);
|
|
// printf("logInfo.tloItemSId-%s\n ", logInfo.tloItemSId);
|
|
}
|
|
|
|
void setCallId(LVCSR_DATA_LOGINFO *logInfo, char* callId, int size) {
|
|
// memset(logInfo.tloItemCallId, 0, 61);
|
|
// memcpy(logInfo.tloItemCallId, callId, size);
|
|
sprintf(logInfo->tloItemCallId, "%s", callId);
|
|
// printf("logInfo.tloItemCallId-%s\n ", logInfo.tloItemSId);
|
|
}
|
|
|
|
void setTrId(LVCSR_DATA_LOGINFO *logInfo, char* trId, int size) {
|
|
// memset(logInfo.tloItemTransactionId, 0, 101);
|
|
// memcpy(logInfo.tloItemTransactionId, trId, size);
|
|
sprintf(logInfo->tloItemTransactionId, "%s", trId);
|
|
// printf("logInfo.tloItemTransactionId-%s\n ", logInfo.tloItemTransactionId);
|
|
}
|
|
|
|
void setItemStartMessage(LVCSR_DATA_LOGINFO *logInfo, char* tloTime, int size) {
|
|
// memset(logInfo.tloItemStartMessage, 0, 101);
|
|
// memcpy(logInfo.tloItemStartMessage, trId, size);
|
|
sprintf(logInfo->tloItemStartMessage, "%s", tloTime);
|
|
// printf("logInfo.tloItemStartMessage-%s\n ", logInfo.tloItemStartMessage);
|
|
}
|
|
|
|
long getSTTSockID(LVCSR_SOCK_HEAD sockhead) {
|
|
return sockhead.uSock;
|
|
}
|
|
|
|
*/
|
|
import "C"
|
|
import (
|
|
"fmt"
|
|
"mybatch/icserror"
|
|
"mybatch/icslog"
|
|
"runtime/debug"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
"unsafe"
|
|
|
|
// "git.icomsys.co.kr/icomsys/voicegateway/voiceagent/icsconf"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const (
|
|
CONNECT_TIMEOUT = 3
|
|
READ_CONNECT_TIMEOUT = 5
|
|
READ_CONNECT_TIMEOUT_LONGVOICE = 10
|
|
|
|
// model Info
|
|
MODEL_ID = 0
|
|
KWD_ID = -1
|
|
CODEC_TYPE = 0 // 8k
|
|
LANGUAGE = 1 // utf-8
|
|
USED_EPD = 1 // epd used
|
|
NO_USED_EPD = 0 // epd used
|
|
//USED_EPD = 1 // epd used
|
|
USED_SCORE = 0 // used off
|
|
)
|
|
|
|
type STTSelvas struct {
|
|
sessionID int
|
|
//handle int
|
|
authCode string
|
|
//ch int
|
|
sttID C.long
|
|
text string
|
|
voiceBuf []byte
|
|
voiceBufCur int64
|
|
silencenum int
|
|
validnum int64 //rms counter
|
|
uDataSize int
|
|
uEndOfSpeech int
|
|
STTInfo STTInfo
|
|
IsClose bool
|
|
SpeechStatus int
|
|
RecordFilePath string
|
|
RecordStart *bool
|
|
rrData *RRData
|
|
M *sync.Mutex
|
|
txNum int //number of sending stt audio packet
|
|
callID string
|
|
custID string
|
|
sreserved string
|
|
trid string
|
|
errCode string
|
|
errFunName string
|
|
errMsg string
|
|
result string
|
|
reqTime time.Time
|
|
rspTime time.Time
|
|
svcReqTime time.Time
|
|
svcRspTime time.Time
|
|
sttcount int
|
|
sttStatus int
|
|
//icsstat.StatInfos
|
|
language string
|
|
}
|
|
|
|
type STTInfo struct {
|
|
LVCSR_SOCK_HEAD C.LVCSR_SOCK_HEAD
|
|
LVCSR_EPD_INFO C.LVCSR_EPD_INFO
|
|
LVCSR_DATA_AUTHENTICATION C.LVCSR_DATA_AUTHENTICATION
|
|
LVCSR_RECOG_RESULT C.LVCSR_RECOG_RESULT
|
|
LVCSR_DATA_RESULT C.LVCSR_DATA_RESULT
|
|
LVCSR_RECOG_MID_RESULT C.LVCSR_RECOG_MID_RESULT
|
|
LVCSR_DATA_INFO C.LVCSR_DATA_INFO
|
|
LVCSR_DATA_LOGINFO C.LVCSR_DATA_LOGINFO
|
|
LVCSR_ERROR_RESULT C.LVCSR_ERROR_RESULT
|
|
}
|
|
|
|
type STTSResult struct {
|
|
result string
|
|
error *icserror.IcsError
|
|
}
|
|
type NewSTTResult struct {
|
|
Res string
|
|
NStart int
|
|
NEnd int
|
|
}
|
|
|
|
func (s STTSelvas) GetTrID() string {
|
|
return s.trid
|
|
}
|
|
|
|
// connect SELVAS STT Server
|
|
func NewSTTS(IP string, port int, callID string, custID string, filePath string) (*STTSelvas, *icserror.IcsError) {
|
|
//func NewSTTS(sid int, IP string, port int, callID string, custID string, filePath string, sreserved string, statOK bool) (*STTSelvas, *icserror.IcsError) {
|
|
l := icslog.InitializeLogger()
|
|
var derr *icserror.IcsError = nil
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
switch v := err.(type) {
|
|
case error:
|
|
icserror.ICSERRSTTFailInit.SetError(v)
|
|
l.Printf("PANIC! %s\n%s", icserror.ICSERRSTTFailInit.GetError().Error(), string(debug.Stack()))
|
|
default:
|
|
l.Print(icserror.ICSERRSTTFailInit.GetError().Error())
|
|
}
|
|
}
|
|
derr = icserror.ICSERRSTTFailInit
|
|
}()
|
|
|
|
if len(IP) <= 0 || port <= 0 {
|
|
derr = icserror.ICSERRInvalidParam
|
|
return nil, derr
|
|
}
|
|
|
|
stts := STTSelvas{authCode: "LGUPlusManager", uDataSize: 1600, uEndOfSpeech: 0, IsClose: false, SpeechStatus: 0, reqTime: time.Now(), svcReqTime: time.Time{}, svcRspTime: time.Time{}, callID: callID, custID: custID, result: "", errCode: "", errMsg: "", errFunName: ""}
|
|
//stts := STTSelvas{handle: -1, authCode: "LGUPlusManager", uDataSize: 1600, uEndOfSpeech: 0, IsClose: false}
|
|
|
|
stts.M = &sync.Mutex{}
|
|
stts.txNum = 0
|
|
|
|
//recording
|
|
stts.RecordFilePath = filePath
|
|
stts.RecordStart = new(bool)
|
|
*stts.RecordStart = false
|
|
stts.rrData = NewRRData(960000) //60sec
|
|
|
|
csIP := C.CString(IP)
|
|
defer C.free(unsafe.Pointer(csIP))
|
|
csPort := C.long(port)
|
|
csConTimeout := C.long(CONNECT_TIMEOUT)
|
|
csReadTimeout := C.long(READ_CONNECT_TIMEOUT)
|
|
|
|
// 셀바스 API는 현재 통합통계가 있어야 동작을함
|
|
trID := uuid.New().String()
|
|
trID = strings.ReplaceAll(trID, "-", "a")
|
|
stts.trid = trID
|
|
|
|
/*
|
|
if stts.sttStatus == STTMemo {
|
|
return &stts, nil
|
|
}
|
|
*/
|
|
|
|
//svcReqTime := time.Now()
|
|
l.Printf("STT ASR_SVC_OPEN Start")
|
|
rc := C.ASR_SVC_OPEN(csIP, csPort, csConTimeout, csReadTimeout, &stts.STTInfo.LVCSR_SOCK_HEAD) // add LVCSR_SOCK_HEAD
|
|
if int(rc) == -1 {
|
|
////////////////테스트코드/////////////////////
|
|
rc = C.ASR_SVC_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_GET_ERROR Fail.. %d", int(stts.sttID), rc)
|
|
// return "", derr
|
|
} else {
|
|
l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s", int(stts.sttID), stts.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&stts.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0]))
|
|
}
|
|
l.Printf("STT ASR_SVC_OPEN Fail - rc:%d", rc)
|
|
derr = icserror.ICSERRSTTConnectTimeout
|
|
return nil, derr
|
|
} else if int(rc) == -2 {
|
|
l.Printf("STT ASR_SVC_OPEN Fail - rc:%d", rc)
|
|
////////////////테스트코드/////////////////////
|
|
rc = C.ASR_SVC_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_GET_ERROR Fail.. %d", int(stts.sttID), rc)
|
|
// return "", derr
|
|
} else {
|
|
l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s ", int(stts.sttID), stts.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&stts.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0]))
|
|
}
|
|
///////////////////////////////////////////////
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
// 통합통계
|
|
now := time.Now()
|
|
tloTime := fmt.Sprintf("%d%02d%02d%02d%02d%02d", now.Year(), int(now.Month()), now.Day(), now.Hour(), now.Minute(), now.Minute())
|
|
csTrId := C.CString(trID)
|
|
defer C.free(unsafe.Pointer(csTrId))
|
|
csCallId := C.CString(callID)
|
|
defer C.free(unsafe.Pointer(csCallId))
|
|
csTloTime := C.CString(tloTime)
|
|
defer C.free(unsafe.Pointer(csTloTime))
|
|
csCustID := C.CString(custID)
|
|
defer C.free(unsafe.Pointer(csCustID))
|
|
|
|
C.setSid(&stts.STTInfo.LVCSR_DATA_LOGINFO, csCustID, C.int(len(custID)))
|
|
C.setCallId(&stts.STTInfo.LVCSR_DATA_LOGINFO, csCallId, C.int(len(callID)))
|
|
C.setTrId(&stts.STTInfo.LVCSR_DATA_LOGINFO, csTrId, C.int(len(trID)))
|
|
C.setItemStartMessage(&stts.STTInfo.LVCSR_DATA_LOGINFO, csTloTime, C.int(len(tloTime)))
|
|
|
|
l.Printf("[%d] SET ASR_SVC_SET_LOGINFO > trID:%s, callID:%s, tloTime:%+v, custID:%s", int(stts.sttID), trID, callID, tloTime, custID)
|
|
//svcReqTime = time.Now()
|
|
rs := C.ASR_SVC_SET_LOGINFO(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_LOGINFO) // 통합통계 설정
|
|
//ljhwan
|
|
//rs = 0
|
|
if int(rs) < 0 {
|
|
l.Printf("[%d] STT ASR_SVC_SET_LOGINFO Fail Result rs:%d, LVCSR_DATA_LOGINFO: %+v", int(stts.sttID), rs, stts.STTInfo.LVCSR_DATA_LOGINFO)
|
|
////////////////테스트코드/////////////////////
|
|
rc = C.ASR_SVC_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_GET_ERROR Fail..", int(stts.sttID))
|
|
// return "", derr
|
|
} else {
|
|
l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s", int(stts.sttID), stts.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&stts.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0]))
|
|
}
|
|
///////////////////////////////////////////////
|
|
|
|
// Server Close
|
|
//svcReqTime = time.Now()
|
|
l.Printf("[%d] STT ASR_SVC_CLOS Start", int(stts.sttID))
|
|
rc = C.ASR_SVC_CLOS(&stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] STT ASR_SVC_CLOS Fail Result rs:%d", int(stts.sttID), rs)
|
|
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
|
|
// Channel Connect
|
|
//svcReqTime = time.Now()
|
|
l.Printf("[%d] STT ASR_SVC_RECG_OPEN Start", int(stts.sttID))
|
|
rc = C.ASR_SVC_RECG_OPEN(&stts.STTInfo.LVCSR_SOCK_HEAD) // add LVCSR_SOCK_HEAD
|
|
//ljhwan
|
|
//rc = 0
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] STT ASR_SVC_RECG_OPEN Fail, LVCSR_SOCK_HEAD: %+v\r\n", int(stts.sttID), stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
// Server Close
|
|
//svcReqTime = time.Now()
|
|
l.Printf("[%d] STT ASR_SVC_CLOS Start", int(stts.sttID))
|
|
rc = C.ASR_SVC_CLOS(&stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d]STT ASR_SVC_CLOS Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
|
|
// Set Model List
|
|
stts.STTInfo.LVCSR_DATA_INFO.nModelId = MODEL_ID
|
|
stts.STTInfo.LVCSR_DATA_INFO.nKwdId = KWD_ID
|
|
stts.STTInfo.LVCSR_DATA_INFO.nCodecType = CODEC_TYPE
|
|
stts.STTInfo.LVCSR_DATA_INFO.nCharSet = LANGUAGE
|
|
// if stts.sttStatus == STTMemo {
|
|
// stts.STTInfo.LVCSR_DATA_INFO.bEpdUsed = NO_USED_EPD
|
|
// } else {
|
|
// stts.STTInfo.LVCSR_DATA_INFO.bEpdUsed = USED_EPD
|
|
// }
|
|
stts.STTInfo.LVCSR_DATA_INFO.bScoreUsed = USED_SCORE
|
|
|
|
//svcReqTime = time.Now()
|
|
rc = C.ASR_SVC_RECG_SET_LIST(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_INFO)
|
|
//ljhwan
|
|
//rc = 0
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d]STT ASR_SVC_RECG_SET_LIST Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v, stts.STTInfo.LVCSR_DATA_INFO: %+v", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD, stts.STTInfo.LVCSR_DATA_INFO)
|
|
|
|
// Channel Connection Close
|
|
//svcReqTime = time.Now()
|
|
l.Printf("[%d]STT ASR_SVC_RECG_CLOS Start", int(stts.sttID))
|
|
rc = C.ASR_SVC_RECG_CLOS(&stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d]STT ASR_SVC_RECG_CLOS Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
derr = icserror.ICSERRTTSNotInit
|
|
}
|
|
|
|
// Server Close
|
|
l.Printf("[%d]STT ASR_SVC_CLOS Start", int(stts.sttID))
|
|
//svcReqTime = time.Now()
|
|
rc = C.ASR_SVC_CLOS(&stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d]STT ASR_SVC_CLOS Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD)
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return nil, derr
|
|
}
|
|
|
|
l.Printf("[%d]Selvas STT New Connection > callID:'%s',trID:'%s'", int(stts.sttID), callID, trID)
|
|
// fmt.Println("STT: Selvas STT New Connection")
|
|
|
|
return &stts, derr
|
|
}
|
|
|
|
func (s *STTSelvas) Close(save bool) (string, string, *icserror.IcsError) {
|
|
if s == nil {
|
|
return "", "", icserror.ICSERRSTTNotInit
|
|
}
|
|
|
|
l := icslog.InitializeLogger()
|
|
// conf := icsconf.GetIcsConfig()
|
|
var derr *icserror.IcsError = nil
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
switch v := err.(type) {
|
|
case error:
|
|
icserror.ICSERRSTTFailInit.SetError(v)
|
|
l.Printf("PANIC! %s\n%s", icserror.ICSERRSTTFailInit.GetError().Error(), string(debug.Stack()))
|
|
default:
|
|
l.Print(icserror.ICSERRSTTFailInit.GetError().Error())
|
|
}
|
|
derr = icserror.ICSERRSTTFailInit
|
|
return
|
|
}
|
|
// derr = icserror.ICSERRSTTFailInit
|
|
}()
|
|
|
|
//l.Printf(icslog.LOG_LEVEL_WARN, s.sessionID, "[%d]STT CLOSE : %s", int(s.sttID), string(debug.Stack()))
|
|
l.Printf("Close STT[%d]. Send Audio Packet Num: %d", int(s.sttID), s.txNum)
|
|
/*
|
|
if s.handle < 0 || s.ch < 0 {
|
|
fmt.Println("selvas stt", s.ch)
|
|
return icserror.ICSERRSTTNotInit
|
|
}
|
|
*/
|
|
|
|
s.M.Lock()
|
|
s.IsClose = true
|
|
s.M.Unlock()
|
|
|
|
var localPath, URL string
|
|
|
|
if *s.RecordStart {
|
|
if save {
|
|
// aud := s.rrData.GetAudio()
|
|
// audLen := len(aud)
|
|
|
|
// 여기 수정해야함
|
|
|
|
// path, ymd, serr := icsutil.Save(aud, s.RecordFilePath, conf.AppInfo.VoiceConfig.Path, true)
|
|
// //path, ymd := Save(s.rrData.GetAudio(), s.RecordFilePath, conf.VoiceConfig.Path, true)
|
|
// if serr == nil {
|
|
// if len(path) == 0 {
|
|
// l.Printf(icslog.LOG_LEVEL_WARN, s.sessionID, "[%d]Failed to save STT voice : %s", int(s.sttID), s.RecordFilePath)
|
|
// } else {
|
|
// localPath = path
|
|
// URL = fmt.Sprintf("%s%s/%s.wav", conf.AppInfo.VoiceConfig.HTTPPath, ymd, s.RecordFilePath)
|
|
// s.RecordFilePath = ""
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.sessionID, "[%d]Saved STT voice(%d). path: %s, URL: %s", int(s.sttID), audLen, localPath, URL)
|
|
// }
|
|
// } else {
|
|
// l.Printf(icslog.LOG_LEVEL_WARN, s.sessionID, "[%d]Failed to save STT voice(%d) : %s, %s - %s", int(s.sttID), audLen, s.RecordFilePath, conf.AppInfo.VoiceConfig.Path, serr.GetMessage())
|
|
// }
|
|
}
|
|
}
|
|
*s.RecordStart = false
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_DEBUG2, s.sessionID, "[%d]STT ASR_SVC_RECG_CLOS. sock header: %+v", int(s.sttID), s.STTInfo.LVCSR_SOCK_HEAD.uSock)
|
|
|
|
//l.Printf(icslog.LOG_LEVEL_INFO, s.sessionID, "[%d] s.STTInfo.LVCSR_RECOG_RESULT Start - s.STTInfo.LVCSR_RECOG_RESULT:%+v", int(s.sttID), s.STTInfo.LVCSR_RECOG_RESULT)
|
|
rc := C.ASR_SVC_RECG_PROC_FREE(&s.STTInfo.LVCSR_RECOG_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("Failed to free STT result[%d]. rc: %d", int(s.sttID), rc)
|
|
if strings.Compare(s.errCode, "54000013") != 0 {
|
|
s.errCode, s.errMsg, s.errFunName = "54000010", "Fail", "ASR_SVC_RECG_PROC_FREE"
|
|
}
|
|
derr = icserror.ICSERRSTTFreeError
|
|
// s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "ASR_SVC_RECG_PROC_FREE", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, svcReqTime, time.Now())
|
|
}
|
|
|
|
// Channel Connection Close
|
|
l.Printf("Close STT channel[%d]", int(s.sttID))
|
|
rc = C.ASR_SVC_RECG_CLOS(&s.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Printf("Failed to close STT channel[%d], rc: %d", int(s.sttID), rc)
|
|
if s.result == "$NO_RESULT$" {
|
|
s.errCode, s.errMsg, s.errFunName = "20000003", "Success", ""
|
|
} else if strings.Compare(s.errCode, "54000013") != 0 {
|
|
s.errCode, s.errMsg, s.errFunName = "54000011", "Fail", "ASR_SVC_RECG_CLOS"
|
|
}
|
|
derr = icserror.ICSERRTTSNotInit
|
|
// s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "ASR_SVC_RECG_CLOS", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, svcReqTime, time.Now())
|
|
}
|
|
|
|
// Server Close
|
|
l.Printf("Close STT SVC[%d]", int(s.sttID))
|
|
rc = C.ASR_SVC_CLOS(&s.STTInfo.LVCSR_SOCK_HEAD)
|
|
//ljhwan
|
|
//rc = 0
|
|
if int(rc) < 0 {
|
|
l.Printf("Failed to close STT SVC[%d], rc: %d", int(s.sttID), rc)
|
|
derr = icserror.ICSERRTTSNotInit
|
|
if strings.Compare(s.errCode, "54000013") != 0 {
|
|
s.errCode, s.errMsg, s.errFunName = "54000012", "Fail", "ASR_SVC_CLOS"
|
|
}
|
|
// s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "ASR_SVC_CLOS", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, s.svcReqTime, time.Now())
|
|
// return derr
|
|
}
|
|
l.Printf("Closed STT[%d] sock header: %+v", int(s.sttID), s.STTInfo.LVCSR_SOCK_HEAD.uSock)
|
|
|
|
s.rrData.Clear()
|
|
|
|
l.Printf("Selvas STT Close - %d. %s", s.voiceBufCur, string(debug.Stack()))
|
|
|
|
return localPath, URL, derr
|
|
}
|
|
|
|
func (s *STTSelvas) GetSTTStatus() bool {
|
|
if s == nil {
|
|
// fmt.Println("get status: stt handle nil")
|
|
return false
|
|
}
|
|
s.M.Lock()
|
|
b := s.IsClose
|
|
s.M.Unlock()
|
|
|
|
return b
|
|
}
|
|
|
|
type AsyncCBFunc func(sttResult string, epd int, inout bool)
|
|
|
|
func (s *STTSelvas) SendSTT(voicedata []byte, final bool, cbFunc AsyncCBFunc) (NewSTTResult, *icserror.IcsError) {
|
|
l := icslog.InitializeLogger()
|
|
var res NewSTTResult
|
|
var derr *icserror.IcsError = nil
|
|
var result string
|
|
// var sendCount int
|
|
|
|
if s == nil {
|
|
derr = icserror.ICSERRTTSNotInit
|
|
l.Println("STTSelvas struct is not initialized")
|
|
return res, derr
|
|
}
|
|
|
|
// // setting the language
|
|
// cLanguage := C.CString(language)
|
|
// defer C.free(unsafe.Pointer(cLanguage))
|
|
// rc := C.ASR_SVC_SET_PARAM(&s.sttInfo.LVCSR_SOCK_HEAD, C.LVCSR_PARAM_TYPE_LANGUAGE, cLanguage)
|
|
// if rc != 0 {
|
|
// return "", icserror.ICSERRSTTLanguageSetting
|
|
// }
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
switch v := err.(type) {
|
|
case error:
|
|
icserror.ICSERRSTTSendFail.SetError(v)
|
|
l.Printf("PANIC! %s\n%s", icserror.ICSERRSTTSendFail.GetError().Error(), string(debug.Stack()))
|
|
default:
|
|
l.Print(icserror.ICSERRSTTSendFail.GetError().Error())
|
|
}
|
|
}
|
|
derr = icserror.ICSERRSTTSendFail
|
|
}()
|
|
|
|
s.uEndOfSpeech = 1
|
|
|
|
//recording audio
|
|
if *s.RecordStart {
|
|
s.rrData.AddAudio(voicedata)
|
|
} else {
|
|
s.rrData.AddTempAudio(voicedata)
|
|
}
|
|
|
|
csUDataSize := C.long(s.uDataSize)
|
|
csUEndSpeech := C.long(s.uEndOfSpeech)
|
|
csBuff := (*C.char)(unsafe.Pointer(&voicedata))
|
|
//csBuff := (*C.char)(unsafe.Pointer(&buff1[0]))
|
|
rc := C.ASR_SVC_RECG_DATA(&s.STTInfo.LVCSR_SOCK_HEAD,
|
|
csBuff,
|
|
csUDataSize,
|
|
csUEndSpeech,
|
|
&s.STTInfo.LVCSR_EPD_INFO)
|
|
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_RECG_DATA ERROR %d", int(s.sttID), rc)
|
|
////////////////테스트코드/////////////////////
|
|
rc = C.ASR_SVC_GET_ERROR(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_ERROR_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_GET_ERROR Fail.. %d", int(s.sttID), rc)
|
|
// return "", derr
|
|
} else {
|
|
l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s", int(s.sttID), s.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&s.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0]))
|
|
}
|
|
///////////////////////////////////////////////
|
|
|
|
s.errCode, s.errMsg, s.errFunName = "54000013", "Fail", "ASR_SVC_RECG_DATA"
|
|
if cbFunc != nil {
|
|
cbFunc("", 99, true)
|
|
}
|
|
derr = icserror.ICSERRSTTSendFail
|
|
return res, derr
|
|
}
|
|
|
|
s.txNum++
|
|
|
|
rc = C.ASR_SVC_RECG_STR_PROC(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_RESULT)
|
|
s.svcRspTime = time.Now()
|
|
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d]!!!! ASR_SVC_RECG_STR_PROC Fail - rc:%d, s.STTInfo.LVCSR_RECOG_RESULT:%+v", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_RESULT)
|
|
// s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "ASR_SVC_RECG_STR_PROC"
|
|
s.result = "$NO_RESULT$"
|
|
derr = icserror.ICSERRSTTSendFail
|
|
if cbFunc != nil {
|
|
cbFunc("", 2, true)
|
|
}
|
|
return res, icserror.ICSERRSTTContinue // 묵음으로 처리
|
|
}
|
|
|
|
result = C.GoString(s.STTInfo.LVCSR_RECOG_RESULT.pResult)
|
|
l.Printf("STT ID[%d] result: %s, result: %p, pointer: %p", int(s.sttID), result, &result, s.STTInfo.LVCSR_RECOG_RESULT.pResult)
|
|
results := ""
|
|
if s.STTInfo.LVCSR_RECOG_RESULT.nResultLen == 0 { // 길이 0일때 값 nil로 나옴
|
|
result = ""
|
|
}
|
|
//result = "TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST"
|
|
s.result = result
|
|
results = result
|
|
if result == "$NO_RESULT$" {
|
|
results = ""
|
|
}
|
|
if cbFunc != nil {
|
|
cbFunc(results, int(s.STTInfo.LVCSR_EPD_INFO), true)
|
|
}
|
|
|
|
// jiyounc
|
|
// return "", icserror.ICSERRSTTContinue
|
|
|
|
res = NewSTTResult{
|
|
Res: results,
|
|
NStart: int(s.STTInfo.LVCSR_DATA_RESULT.nStart),
|
|
NEnd: int(s.STTInfo.LVCSR_DATA_RESULT.nEnd),
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// result return
|
|
func NewSTTSResult(result string, err *icserror.IcsError) *STTSResult {
|
|
return &STTSResult{result, err}
|
|
}
|
|
|
|
// 말을 하지 않았을때 결과 조회
|
|
func (s *STTSelvas) GetSTTResultToStopSTT() (string, *icserror.IcsError) {
|
|
l := icslog.InitializeLogger()
|
|
if s == nil {
|
|
return "", icserror.ICSERRSTTNotInit
|
|
}
|
|
|
|
l.Printf("[%d] LVCSR_RECOG_RESULT: %+v, LVCSR_RECOG_RESULT:%+v", int(s.sttID), &s.STTInfo.LVCSR_RECOG_RESULT, s.STTInfo.LVCSR_RECOG_RESULT)
|
|
rc := C.ASR_SVC_RECG_STR_PROC(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_RECG_STR_PROC Fail - rc:%d, s.STTInfo.LVCSR_RECOG_RESULT:%+v", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_RESULT)
|
|
s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "ASR_SVC_RECG_STR_PROC"
|
|
// s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "ASR_SVC_RECG_STR_PROC", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, svcReqTime, time.Now())
|
|
return "", icserror.ICSERRSTTSendFail
|
|
}
|
|
return "", icserror.ICSERRSTTContinue
|
|
}
|
|
|
|
// epd 1 이후 end 전송 => 결과조회
|
|
func (s *STTSelvas) SendSTTProcGetResult() (string, *icserror.IcsError) {
|
|
l := icslog.InitializeLogger()
|
|
var derr *icserror.IcsError = nil
|
|
if s == nil {
|
|
return "", icserror.ICSERRSTTNotInit
|
|
}
|
|
|
|
// buff1 := make([]byte, 0)
|
|
s.uEndOfSpeech = 1
|
|
uDataSize := 0
|
|
csUDataSize := C.long(uDataSize)
|
|
csUEndSpeech := C.long(s.uEndOfSpeech)
|
|
// csBuff := nil
|
|
|
|
l.Printf("[%d] LVCSR_RECOG_RESULT: %+v, LVCSR_RECOG_RESULT:%+v", int(s.sttID), &s.STTInfo.LVCSR_RECOG_RESULT, s.STTInfo.LVCSR_RECOG_RESULT)
|
|
// svcReqTime := time.Now()
|
|
rc := C.ASR_SVC_RECG_DATA(&s.STTInfo.LVCSR_SOCK_HEAD,
|
|
nil,
|
|
csUDataSize,
|
|
csUEndSpeech,
|
|
&s.STTInfo.LVCSR_EPD_INFO)
|
|
if int(rc) < 0 {
|
|
l.Printf("[%d] ASR_SVC_RECG_STR_PROC Fail - rc:%d, s.STTInfo.LVCSR_RECOG_RESULT:%+v", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_RESULT)
|
|
derr = icserror.ICSERRSTTSendFail
|
|
s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "ASR_SVC_RECG_STR_PROC"
|
|
// s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "ASR_SVC_RECG_DATA", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, svcReqTime, time.Now())
|
|
return "", derr
|
|
}
|
|
|
|
s.GetSTTResultToStopSTT()
|
|
// l.Print(icslog.LOG_LEVEL_INFO, s.sessionID, "Request Recg Result")
|
|
// rc = C.ASR_SVC_RECG_PROC(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_RESULT)
|
|
// if int(rc) < 0 {
|
|
// derr = icserror.ICSERRSTTFail
|
|
// return "", derr
|
|
// }
|
|
return "", nil
|
|
}
|
|
|
|
func (s STTSelvas) GetAudio() []byte {
|
|
return s.rrData.GetAudio()
|
|
}
|
|
|
|
func (s STTSelvas) GetReqTime() time.Time {
|
|
return s.reqTime
|
|
}
|
|
|
|
func (s *STTSelvas) CloseChanelAndServer() (bool, *icserror.IcsError) {
|
|
// 서버 결과에 사용된 메모리 초기화
|
|
rc := C.ASR_SVC_RECG_PROC_FREE(&s.STTInfo.LVCSR_RECOG_RESULT)
|
|
if int(rc) < 0 {
|
|
l.Println("Error occured while executing ASR_SVC_RECG_PROC_FREE()")
|
|
return false, icserror.ICSERRSTTConnectCloseFail
|
|
}
|
|
// 채널 해제
|
|
rc = C.ASR_SVC_RECG_CLOS(&s.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Println("Error occured while executing ASR_SVC_RECG_CLOS()")
|
|
return false, icserror.ICSERRSTTConnectCloseFail
|
|
}
|
|
// stt 서버 종료
|
|
rc = C.ASR_SVC_CLOS(&s.STTInfo.LVCSR_SOCK_HEAD)
|
|
if int(rc) < 0 {
|
|
l.Println("Error occured while executing ASR_SVC_CLOS()")
|
|
return false, icserror.ICSERRSTTConnectCloseFail
|
|
}
|
|
s.rrData.Clear()
|
|
return true, nil
|
|
|
|
}
|