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

//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
}