// go:build !test //go:build !test // +build !test // for STT SELVAS STT package icsstt /* #cgo LDFLAGS: -lstdc++ -ldl ./extlib/selvasstt/SDK/LIB/c_linux/x64/libSTTLIB.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 #include #include #include #include char* getResultData(LVCSR_DATA_RESULT* pDataResult, int nCount) { char* skip1 = ""; char* space = " "; int len = 0; int i; for (i = 0; i < nCount; i++) { int maxLength = 50 + strlen(pDataResult[i].pTokenStr); char* strResult = malloc(sizeof(char) * maxLength); sprintf(strResult, "%u|%u|%s\n", pDataResult[i].nStart, pDataResult[i].nEnd, pDataResult[i].pTokenStr); len += strlen(strResult) + 1; printf("%ld|%ld\n", pDataResult[i].nStart, pDataResult[i].nEnd); free(strResult); } char* result = malloc(sizeof(char) * (len + 50)); strcpy(result, ""); for (i = 0; i < nCount; i++) { int maxLength = 50 + strlen(pDataResult[i].pTokenStr); char* strResult = malloc(sizeof(char) * maxLength); sprintf(strResult, "%u|%u|%s\n", pDataResult[i].nStart, pDataResult[i].nEnd, pDataResult[i].pTokenStr); if (strcmp(pDataResult[i].pTokenStr,skip1) == 0) { } else { strcat(result, space); strcat(result, strResult); } free(strResult); } return result; } // char* getResultStrData(LVCSR_DATA_RESULT* pResultStr) { // char* skip1 = ""; // 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("pResultStr : %s\n", midResult->pResultStr); printf("flag : %d\n", midResult->bEngineDetectionFlag); printf("count: %ld\n\n", midResult->nDataCnt); } 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); } void setConnId(LVCSR_DATA_CALLINFO *callInfo, char* sid, int size) { callInfo->pConnIdStr = (char*)malloc(size + 1); memset(callInfo->pConnIdStr, 0, size + 1); callInfo->nConnIdLen = size; sprintf(callInfo->pConnIdStr, "%s", sid); // printf("logInfo.tloItemSID-%s\n ", logInfo.tloItemSID); } void setCallDateTime(LVCSR_DATA_CALLINFO *callInfo, unsigned long callDatetime) { // memset(logInfo.tloItemCallID, 0, 61); // memcpy(logInfo.tloItemCallID, callId, size); LVCSR_DATE_TIMESTAMP pCallDateTime = { 0 }; unsigned long sBaseTimeMillis = time(NULL); SelvySTT_GET_TIMESTAMP(sBaseTimeMillis, &pCallDateTime); callInfo->pCallDateTime = pCallDateTime; //sprintf(logInfo->tloItemCallID, "%s", callId); // printf("logInfo.tloItemCallID-%s\n ", logInfo.tloItemSID); } void freeConnId(LVCSR_DATA_CALLINFO *callInfo) { if (callInfo->pConnIdStr){ free(callInfo->pConnIdStr); callInfo->pConnIdStr = NULL; callInfo->nConnIdLen = 0; } } long getSTTSockID(LVCSR_SOCK_HEAD sockhead) { return sockhead.nSock; } */ import "C" import ( "fmt" "log" "runtime/debug" "strings" "sync" "time" "unsafe" // "git.icomsys.co.kr/icomsys/voicecapture/voiceagent/icsconf" // "git.icomsys.co.kr/icomsys/voicecapture/voiceagent/icserror" // "git.icomsys.co.kr/icomsys/voicecapture/voiceagent/icslog" "batchmodule/icsconf" "batchmodule/icserror" "batchmodule/icslog" "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 ENGINE_EPD_USED_ON = 2 NO_USED_EPD = 0 // epd used //USED_EPD = 1 // epd used USED_SCORE = 0 // used off USED_ASYNC_MID_RESULT_OFF = 0 // mid result USED_ASYNC_MID_RESULT_ON = 1 // mid result DIRECTION_USED_UNK = 0 // Unknown DIRECTION_USED_INB = 1 // Inbound DIRECTION_USED_OB = 2 // Outbound SEG_USED_MONO = 0 // Rx/Tx SEG_USED_RX = 1 // Receiver SEG_USED_TX = 2 // Transmitter SEG_USED_BOT = 3 ) type AsyncCBFunc func(sttResult string, epd int, inout bool) 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 callExt string sreserved string trid string errCode string errMsg string errFunName string result string reqTime time.Time rspTime time.Time svcReqTime time.Time svcRspTime time.Time sttIdx int sttStatus int //icsstat.StatInfos } 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 LVCSR_DATA_CALLINFO C.LVCSR_DATA_CALLINFO } type STTSResult struct { result string error *icserror.IcsError } var ( conf icsconf.AppInfo l *log.Logger ) func init() { conf = icsconf.Getconfig() l = icslog.InitializeLogger() } func (s STTSelvas) GetTrID() string { return s.trid } // connect SELVAS STT Server func NewSTTSshort(IP string, port int, connId string, filePath string, isRx bool, isInbound bool) (*STTSelvas, *icserror.IcsError) { //func NewSTTS(sid int, IP string, port int, callID string, custID string, filePath string, sreserved string, statOK bool) (*STTSelvas, *icserror.IcsError) { var derr *icserror.IcsError = nil l.Println("NewSTTSshort() has started!") defer func() { if err := recover(); err != nil { switch v := err.(type) { case error: icserror.ICSERRSTTFailInit.SetError(v) l.Printf("PANIC! %s\n%s\n", icserror.ICSERRSTTFailInit.GetError().Error(), string(debug.Stack())) default: l.Println(icserror.ICSERRSTTFailInit.GetError().Error()) } } derr = icserror.ICSERRSTTFailInit }() if len(IP) <= 0 || port <= 0 { derr = icserror.ICSERRInvalidParam return nil, derr } // STT 실패 재처리 모듈이라 callId, custId 없어서 connId 넣음. stts := STTSelvas{authCode: "LGUPlusManager", uDataSize: 1600, uEndOfSpeech: 0, IsClose: false, SpeechStatus: 0, reqTime: time.Now(), svcReqTime: time.Time{}, svcRspTime: time.Time{}, callID: connId, custID: connId, 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 = true stts.rrData = NewRRData(960000) //60sec csIP := C.CString(IP) defer C.free(unsafe.Pointer(csIP)) csPort := C.int(port) csConTimeout := C.int(CONNECT_TIMEOUT) csReadTimeout := C.int(READ_CONNECT_TIMEOUT) trID := uuid.New().String() trID = strings.ReplaceAll(trID, "-", "a") stts.trid = trID /* if stts.sttStatus == STTMemo { return &stts, nil } */ //svcReqTime := time.Now() l.Println("STT SelvySTT_INIT Start") rc := C.SelvySTT_INIT(csIP, csPort, csConTimeout, csReadTimeout, &stts.STTInfo.LVCSR_SOCK_HEAD) // add LVCSR_SOCK_HEAD if int(rc) == -1 { ////////////////테스트코드///////////////////// rc = C.SelvySTT_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT) if int(rc) < 0 { l.Printf("[%d] SelvySTT_GET_ERROR Fail.. %d\n", int(stts.sttID), rc) // return "", derr } else { l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s\n", int(stts.sttID), stts.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&stts.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0])) } l.Printf("STT SelvySTT_INIT Fail - rc:%d\n", rc) derr = icserror.ICSERRSTTConnectTimeout return nil, derr } else if int(rc) == -2 { l.Printf("STT SelvySTT_INIT Fail - rc:%d\n", rc) ////////////////테스트코드///////////////////// rc = C.SelvySTT_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT) if int(rc) < 0 { l.Printf("[%d] SelvySTT_GET_ERROR Fail.. %d\n", int(stts.sttID), rc) // return "", derr } else { l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s \n", int(stts.sttID), stts.STTInfo.LVCSR_ERROR_RESULT.nErrorCode, C.GoString(&stts.STTInfo.LVCSR_ERROR_RESULT.pErrorMsg[0])) } /////////////////////////////////////////////// derr = icserror.ICSERRSTTFailInit return nil, derr } // callID = strings.ReplaceAll(callID, "-", "") // if len(callID) > 12 { // callID = callID[:12] // } // l.Printf("callID: %s\n", callID) // if len(callID) == 0 { // callID = trID // } now := time.Now() tloTime := fmt.Sprintf("%d%02d%02d%02d%02d%02d\n", now.Year(), int(now.Month()), now.Day(), now.Hour(), now.Minute(), now.Minute()) csTrId := C.CString(trID) defer C.free(unsafe.Pointer(csTrId)) csConnId := C.CString(connId) defer C.free(unsafe.Pointer(csConnId)) csTloTime := C.CString(tloTime) defer C.free(unsafe.Pointer(csTloTime)) // csCustID := C.CString(custID) csCustID := C.CString(connId) defer C.free(unsafe.Pointer(csCustID)) // connid 없어서 callid로 connid 만들었던 코드. 해당파일에서는 connId 넣어줌 // C.setConnId(&stts.STTInfo.LVCSR_DATA_CALLINFO, csCallId, C.int(len(callID))) C.setConnId(&stts.STTInfo.LVCSR_DATA_CALLINFO, csConnId, C.int(len(connId))) C.setCallDateTime(&stts.STTInfo.LVCSR_DATA_CALLINFO, C.ulong(time.Now().UnixNano())) if isInbound { stts.STTInfo.LVCSR_DATA_CALLINFO.nCallDirection = DIRECTION_USED_INB } else { stts.STTInfo.LVCSR_DATA_CALLINFO.nCallDirection = DIRECTION_USED_OB } if isRx { stts.STTInfo.LVCSR_DATA_CALLINFO.nSpeakerSegmentation = SEG_USED_RX } else { stts.STTInfo.LVCSR_DATA_CALLINFO.nSpeakerSegmentation = SEG_USED_TX } l.Printf("[%d] SET SelvySTT_SET_CALLINFO > connID:%s, direction:%d, speakerSeg:%d\n", int(stts.sttID), C.GoString(stts.STTInfo.LVCSR_DATA_CALLINFO.pConnIdStr), stts.STTInfo.LVCSR_DATA_CALLINFO.nCallDirection, stts.STTInfo.LVCSR_DATA_CALLINFO.nSpeakerSegmentation) // 콜인포 설정 rs := C.SelvySTT_SET_CALLINFO(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_CALLINFO) // rs := C.SelvySTT_SET_LOGINFO(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_LOGINFO) //ljhwan //rs = 0 if int(rs) < 0 { l.Printf("[%d] STT SelvySTT_SET_LOGINFO Fail Result rs:%d, LVCSR_DATA_LOGINFO: %+v\n", int(stts.sttID), rs, stts.STTInfo.LVCSR_DATA_LOGINFO) ////////////////테스트코드///////////////////// rc = C.SelvySTT_GET_ERROR(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_ERROR_RESULT) if int(rc) < 0 { l.Printf("[%d] SelvySTT_GET_ERROR Fail..", int(stts.sttID)) // return "", derr } else { l.Printf("[%d] LVCSR_ERROR_RESULT - [%d]%s\n", 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 SelvySTT_EXIT Start\n", int(stts.sttID)) rc = C.SelvySTT_EXIT(&stts.STTInfo.LVCSR_SOCK_HEAD) if int(rc) < 0 { l.Printf("[%d] STT SelvySTT_EXIT Fail Result rs:%d\n", int(stts.sttID), rs) derr = icserror.ICSERRSTTFailInit return nil, derr } derr = icserror.ICSERRSTTFailInit return nil, derr } C.freeConnId(&stts.STTInfo.LVCSR_DATA_CALLINFO) //svcReqTime = time.Now() // 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.nEpdUsed = NO_USED_EPD // } else { stts.STTInfo.LVCSR_DATA_INFO.nEpdUsed = ENGINE_EPD_USED_ON stts.STTInfo.LVCSR_DATA_INFO.bAsyncMidRstUsed = USED_ASYNC_MID_RESULT_ON // } stts.STTInfo.LVCSR_DATA_INFO.bScoreUsed = USED_SCORE // Channel Connect //svcReqTime = time.Now() l.Printf("[%d] STT SelvySTT_OPEN Start\n", int(stts.sttID)) rc = C.SelvySTT_OPEN(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_INFO) // add LVCSR_SOCK_HEAD //ljhwan //rc = 0 if int(rc) < 0 { l.Printf("[%d] STT SelvySTT_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 SelvySTT_EXIT Start", int(stts.sttID)) rc = C.SelvySTT_EXIT(&stts.STTInfo.LVCSR_SOCK_HEAD) if int(rc) < 0 { l.Printf("[%d]STT SelvySTT_EXIT Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v\n", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD) derr = icserror.ICSERRSTTFailInit return nil, derr } derr = icserror.ICSERRSTTFailInit return nil, derr } // rc = C.SelvySTT_SET_INFO(&stts.STTInfo.LVCSR_SOCK_HEAD, &stts.STTInfo.LVCSR_DATA_INFO) // //ljhwan // //rc = 0 // if int(rc) < 0 { // l.Printf("[%d]STT SelvySTT_SET_INFO Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v, stts.STTInfo.LVCSR_DATA_INFO: %+v\n", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD, stts.STTInfo.LVCSR_DATA_INFO) // // Channel Connection Close // //svcReqTime = time.Now() // l.Printf("[%d]STT SelvySTT_CLOS Start\n", int(stts.sttID)) // rc = C.SelvySTT_CLOS(&stts.STTInfo.LVCSR_SOCK_HEAD) // if int(rc) < 0 { // l.Printf("[%d]STT SelvySTT_CLOS Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v\n", int(stts.sttID), rs, stts.STTInfo.LVCSR_SOCK_HEAD) // derr = icserror.ICSERRTTSNotInit // } // // Server Close // l.Printf("[%d]STT SelvySTT_EXIT Start\n", int(stts.sttID)) // //svcReqTime = time.Now() // rc = C.SelvySTT_EXIT(&stts.STTInfo.LVCSR_SOCK_HEAD) // if int(rc) < 0 { // l.Printf("[%d]STT SelvySTT_EXIT Fail Result rs:%d, LVCSR_SOCK_HEAD: %+v\n", 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'\n", int(stts.sttID), callID, trID) l.Printf("[%d]Selvas STT New Connection > connId:'%s',trID:'%s'\n", int(stts.sttID), connId, trID) return &stts, derr } func (s *STTSelvas) Close() *icserror.IcsError { if s == nil { return icserror.ICSERRSTTNotInit } 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\n", icserror.ICSERRSTTFailInit.GetError().Error(), string(debug.Stack())) default: l.Print(icserror.ICSERRSTTFailInit.GetError().Error()) } derr = icserror.ICSERRSTTFailInit return } // derr = icserror.ICSERRSTTFailInit }() l.Printf("Close STT[%d]. Send Audio Packet Num: %d\n", int(s.sttID), s.txNum) s.M.Lock() s.IsClose = true s.M.Unlock() *s.RecordStart = false rc := C.SelvySTT_CLS_RES(&s.STTInfo.LVCSR_RECOG_RESULT) if int(rc) < 0 { l.Printf("Failed to free STT result[%d]. rc: %d\n", int(s.sttID), rc) if strings.Compare(s.errCode, "54000013") != 0 { s.errCode, s.errMsg, s.errFunName = "54000010", "Fail", "SelvySTT_CLS_RES" } derr = icserror.ICSERRSTTFreeError } // Channel Connection Close l.Printf("Close STT channel[%d]\n", int(s.sttID)) rc = C.SelvySTT_CLOS(&s.STTInfo.LVCSR_SOCK_HEAD) if int(rc) < 0 { l.Printf("Failed to close STT channel[%d], rc: %d\n", 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", "SelvySTT_CLOS" } derr = icserror.ICSERRTTSNotInit } // Server Close l.Printf("Close STT SVC[%d]\n", int(s.sttID)) rc = C.SelvySTT_EXIT(&s.STTInfo.LVCSR_SOCK_HEAD) //ljhwan //rc = 0 if int(rc) < 0 { l.Printf("Failed to close STT SVC[%d], rc: %d\n", int(s.sttID), rc) derr = icserror.ICSERRTTSNotInit if strings.Compare(s.errCode, "54000013") != 0 { s.errCode, s.errMsg, s.errFunName = "54000012", "Fail", "SelvySTT_EXIT" } } l.Printf("Closed STT[%d] sock header: %+v\n", int(s.sttID), s.STTInfo.LVCSR_SOCK_HEAD.nSock) s.rrData.Clear() return 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) func (s *STTSelvas) SendSTT(voicedata []byte, final bool, cbFunc AsyncCBFunc) (string, *icserror.IcsError) { if s == nil { return "", icserror.ICSERRTTSNotInit } var result string var sendCount int var derr *icserror.IcsError = nil var resultsWithTime string defer func() { if err := recover(); err != nil { switch v := err.(type) { case error: icserror.ICSERRSTTSendFail.SetError(v) l.Printf("sttselvas.go>SendSTT()> PANIC! %s\n%s\n", icserror.ICSERRSTTSendFail.GetError().Error(), string(debug.Stack())) default: l.Print(icserror.ICSERRSTTSendFail.GetError().Error()) } } derr = icserror.ICSERRSTTSendFail }() // if s.sttStatus != STTMemo { // Set EPD value if !final { s.uEndOfSpeech = 0 } else { s.uEndOfSpeech = 1 } // file split // sendCount = len(voicedata) / 320 sendCount = len(voicedata) / 1600 // l.Printf("SendSTT voice size: %d, sendCount: %d \n", len(voicedata), sendCount) //start := time.Now() // send voice(voicedata) for j := 0; j < sendCount; j++ { // buff1 := voicedata[320*j : 320*(j+1)] buff1 := voicedata[1600*j : 1600*(j+1)] //recording audio if *s.RecordStart { s.rrData.AddAudio(buff1) } else { s.rrData.AddTempAudio(buff1) } csUDataSize := C.int(s.uDataSize) // if !final && j < sendCount-1 { // s.uEndOfSpeech = 0 // } else { // s.uEndOfSpeech = 1 // } csUEndSpeech := C.int(s.uEndOfSpeech) csBuff := (*C.char)(unsafe.Pointer(&buff1[0])) // l.Printf("SelvySTT_SEND_DATA : %d, size: %d EndofSpeech : %d\n", j, csUDataSize, s.uEndOfSpeech) rc := C.SelvySTT_SEND_DATA(&s.STTInfo.LVCSR_SOCK_HEAD, csBuff, csUDataSize, csUEndSpeech, &s.STTInfo.LVCSR_EPD_INFO) if int(rc) < 0 { l.Printf("sttselvas.go>SendSTT()> [%d] SelvySTT_SEND_DATA ERROR %d\n", int(s.sttID), rc) ////////////////테스트코드///////////////////// rc = C.SelvySTT_GET_ERROR(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_ERROR_RESULT) if int(rc) < 0 { l.Printf("sttselvas.go>SendSTT()> [%d] SelvySTT_GET_ERROR Fail.. %d\n", int(s.sttID), rc) // return "", derr } else { l.Printf("sttselvas.go>SendSTT()> [%d] LVCSR_ERROR_RESULT - [%d]%s\n", 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", "SelvySTT_SEND_DATA" if cbFunc != nil { cbFunc("", 99, true) break } derr = icserror.ICSERRSTTSendFail return "", derr } s.txNum++ if s.STTInfo.LVCSR_EPD_INFO == 1 { //l.Printf("STT ID[%d] LVCSR_EPD_INFO: %d", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO) if s.SpeechStatus == 0 { l.Printf("sttselvas.go>SendSTT()> STT ID[%d] LVCSR_EPD_INFO: %d\n", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO) s.SpeechStatus = 1 if cbFunc != nil { cbFunc(result, int(s.STTInfo.LVCSR_EPD_INFO), true) } } } else if s.STTInfo.LVCSR_EPD_INFO > 1 { l.Printf("sttselvas.go>SendSTT()> LVCSR_EPD_INFO == %d\n", s.STTInfo.LVCSR_EPD_INFO) s.svcReqTime = time.Now() break } } if s.STTInfo.LVCSR_EPD_INFO == 2 || s.STTInfo.LVCSR_EPD_INFO == 5 { // l.Printf("[%d]!!!! LVCSR_EPD_INFO: %d, LVCSR_SOCK_HEAD: %+v", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO, s.STTInfo.LVCSR_SOCK_HEAD) l.Printf("sttselvas.go>SendSTT()> STT ID[%d] LVCSR_EPD_INFO: %d, STT Completed!\n", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO) rc := C.SelvySTT_GET_MIDRES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_MID_RESULT) s.svcRspTime = time.Now() if int(rc) < 0 { l.Printf("sttselvas.go>SendSTT()> [%d]SelvySTT_GET_MIDRES Failed!!! - rc:%d, s.STTInfo.LVCSR_RECOG_MID_RESULT:%+v\n", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_MID_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 "", icserror.ICSERRSTTContinue // 묵음으로 처리 } s.sttIdx++ wg := sync.WaitGroup{} wg.Add(1) go func() { result = C.GoString(s.STTInfo.LVCSR_RECOG_MID_RESULT.pResultStr) resultTocken := C.GoString(s.STTInfo.LVCSR_RECOG_MID_RESULT.pDataResult.pTokenStr) nStartTime := C.int(s.STTInfo.LVCSR_RECOG_MID_RESULT.pDataResult.nStart) nEnd := C.int(s.STTInfo.LVCSR_RECOG_MID_RESULT.pDataResult.nEnd) l.Printf("sttselvas.go>SendSTT()> STT ID[%d] result: %s, result: %p, pointer: %p\n", int(s.sttID), result, &result, s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) l.Printf("sttselvas.go>SendSTT()> STT ID[%d] result: %s, %d, %d\n", int(s.sttID), resultTocken, nStartTime, nEnd) // l.Printf("STT ID[%d] result: %s, result: %p, pointer: %p\n", int(s.sttID), result, &result, s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) results := "" if s.STTInfo.LVCSR_RECOG_MID_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 = "" } resultsWithTime = fmt.Sprintf("%d|%d|%s\n", nStartTime, nEnd, results) if cbFunc != nil { cbFunc(results, int(s.STTInfo.LVCSR_EPD_INFO), true) } //l.Printf("[%d] result Free OK", int(s.sttID)) wg.Done() }() wg.Wait() // 중간결과 구조체 메모리 해제 rc = C.SelvySTT_CLS_MIDRES(&s.STTInfo.LVCSR_RECOG_MID_RESULT) if int(rc) < 0 { l.Println("sttselvas.go>SendSTT()> SelvySTT_CLS_MIDRES Failed!!! MID RES pResultStr: ", s.STTInfo.LVCSR_RECOG_MID_RESULT.pResultStr) } return resultsWithTime, icserror.ICSERRSTTContinue } // } else { // s.uEndOfSpeech = 1 // //recording audio // if *s.RecordStart { // s.rrData.AddAudio(voicedata) // } else { // s.rrData.AddTempAudio(voicedata) // } // csUDataSize := C.int(s.uDataSize) // csUEndSpeech := C.int(s.uEndOfSpeech) // csBuff := (*C.char)(unsafe.Pointer(&voicedata)) // //csBuff := (*C.char)(unsafe.Pointer(&buff1[0])) // rc := C.SelvySTT_SEND_DATA(&s.STTInfo.LVCSR_SOCK_HEAD, // csBuff, // csUDataSize, // csUEndSpeech, // &s.STTInfo.LVCSR_EPD_INFO) // if int(rc) < 0 { // l.Printf("[%d] SelvySTT_SEND_DATA ERROR %d", int(s.sttID), rc) // ////////////////테스트코드///////////////////// // rc = C.SelvySTT_GET_ERROR(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_ERROR_RESULT) // if int(rc) < 0 { // l.Printf("[%d] SelvySTT_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", "SelvySTT_SEND_DATA" // if cbFunc != nil { // cbFunc("", 99, true) // } // derr = icserror.ICSERRSTTSendFail // return "", derr // } // s.txNum++ // rc = C.SelvySTT_GET_MIDRES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_MID_RESULT) // s.svcRspTime = time.Now() // if int(rc) < 0 { // l.Printf("[%d]!!!! SelvySTT_GET_MIDRES Fail - rc:%d, s.STTInfo.LVCSR_RECOG_MID_RESULT:%+v", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_MID_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 "", icserror.ICSERRSTTContinue // 묵음으로 처리 // } // result = C.GoString(s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) // l.Printf("STT ID[%d] result: %s, result: %p, pointer: %p", int(s.sttID), result, &result, s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) // 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) // } // //l.Printf("[%d] result Free OK", int(s.sttID)) // return results, icserror.ICSERRSTTOK // } return "", icserror.ICSERRSTTContinue } // result return func NewSTTSResult(result string, err *icserror.IcsError) *STTSResult { return &STTSResult{result, err} } // 말을 하지 않았을때 결과 조회 func (s *STTSelvas) GetSTTResultToStopSTT() (string, *icserror.IcsError) { l := icslog.GetIcsLog() if s == nil { return "", icserror.ICSERRSTTNotInit } //rc := C.SelvySTT_GET_MIDRES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_MID_RESULT) rc := C.SelvySTT_GET_RES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_RESULT) l.Printf("GetSTTResultToStopSTT rc:%d, [%d] EPDINFO[%d] LVCSR_RECOG_RESULT: %+v, LVCSR_RECOG_RESULT:%+v\n", int(rc), int(s.sttID), s.STTInfo.LVCSR_EPD_INFO, &s.STTInfo.LVCSR_RECOG_RESULT, s.STTInfo.LVCSR_RECOG_RESULT) if int(rc) < 0 { l.Printf("[%d] SelvySTT_GET_MIDRES Fail - rc:%d, s.STTInfo.LVCSR_RECOG_MID_RESULT:%+v\n", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_MID_RESULT) s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "SelvySTT_GET_MIDRES" // 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) { var derr *icserror.IcsError = nil if s == nil { return "", icserror.ICSERRSTTNotInit } //buff1 := make([]byte, 1) s.uEndOfSpeech = 1 uDataSize := 0 csUDataSize := C.int(uDataSize) csUEndSpeech := C.int(s.uEndOfSpeech) //csBuff := (*C.char)(unsafe.Pointer(&buff1[0])) // csBuff := nil // svcReqTime := time.Now() rc := C.SelvySTT_SEND_DATA(&s.STTInfo.LVCSR_SOCK_HEAD, nil, csUDataSize, csUEndSpeech, &s.STTInfo.LVCSR_EPD_INFO) if int(rc) < 0 { l.Printf("[ERR] sttselvas>SendSTTProcGetResult()> [%d] SelvySTT_SEND_DATA Failed - rc:%d, s.STTInfo.LVCSR_RECOG_RESULT:%+v\n", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_RESULT) derr = icserror.ICSERRSTTSendFail s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "SelvySTT_SEND_DATA" // s.SendStasticInfo(s.callID, s.custID, s.trid, "STT", "SelvySTT_SEND_DATA", "54000001", "Fail", "", "", s.reqTime, time.Now(), s.sreserved, svcReqTime, time.Now()) return "", derr } l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> rc:%d, [%d] EPDINFO[%d] LVCSR_RECOG_RESULT: %+v, LVCSR_RECOG_RESULT:%+v\n", int(rc), int(s.sttID), s.STTInfo.LVCSR_EPD_INFO, &s.STTInfo.LVCSR_RECOG_RESULT, s.STTInfo.LVCSR_RECOG_RESULT) if s.STTInfo.LVCSR_EPD_INFO == 2 { // l.Printf("[%d]!!!! LVCSR_EPD_INFO: %d, LVCSR_SOCK_HEAD: %+v", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO, s.STTInfo.LVCSR_SOCK_HEAD) l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> STT ID[%d] LVCSR_EPD_INFO: %d, STT Completed!\n", int(s.sttID), s.STTInfo.LVCSR_EPD_INFO) rc := C.SelvySTT_GET_MIDRES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_MID_RESULT) s.svcRspTime = time.Now() if int(rc) < 0 { l.Printf("[ERR] sttselvas>SendSTTProcGetResult()> [%d] SelvySTT_GET_MIDRES Failed - rc:%d, s.STTInfo.LVCSR_RECOG_MID_RESULT:%+v\n", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_MID_RESULT) // s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "ASR_SVC_RECG_STR_PROC" s.result = "$NO_RESULT$" // derr = icserror.ICSERRSTTSendFail return "", icserror.ICSERRSTTContinue // 묵음으로 처리 } wg := sync.WaitGroup{} wg.Add(1) go func() { result := C.GoString(s.STTInfo.LVCSR_RECOG_MID_RESULT.pResultStr) l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> STT ID[%d] result: %s, result: %p, pointer: %p\n", int(s.sttID), result, &result, s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) results := "" if s.STTInfo.LVCSR_RECOG_MID_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 = "" } l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> results: %s", results) //l.Printf("[%d] result Free OK", int(s.sttID)) wg.Done() }() wg.Wait() } // 중간결과 구조체 메모리 해제 rc = C.SelvySTT_CLS_MIDRES(&s.STTInfo.LVCSR_RECOG_MID_RESULT) if int(rc) < 0 { l.Println("[ERR] sttselvas>SendSTTProcGetResult()> SelvySTT_CLS_MIDRES Failed. LVCSR_RECOG_MID_RESULT.pResultStr: ", s.STTInfo.LVCSR_RECOG_MID_RESULT.pResultStr) } // 최종 결과 호출 rc = C.SelvySTT_GET_RES(&s.STTInfo.LVCSR_SOCK_HEAD, &s.STTInfo.LVCSR_RECOG_RESULT) if int(rc) < 0 { l.Printf("[ERR] sttselvas>SendSTTProcGetResult()> [%d] SelvySTT_GET_RES Fail - rc:%d, s.STTInfo.SelvySTT_GET_RES:%+v\n", int(s.sttID), rc, s.STTInfo.LVCSR_RECOG_RESULT) derr = icserror.ICSERRSTTSendFail s.errCode, s.errMsg, s.errFunName = "54000009", "Fail", "SelvySTT_GET_RES" return "", derr } dataCnt := int(s.STTInfo.LVCSR_RECOG_RESULT.nDataCnt) resultLen := int(s.STTInfo.LVCSR_RECOG_RESULT.nResultLen) pResultStr := C.GoString(s.STTInfo.LVCSR_RECOG_RESULT.pResultStr) l.Printf("dataCnt: %d", dataCnt) l.Printf("resultLen: %d", resultLen) if pResultStr != "" { strresult := C.getResultData(s.STTInfo.LVCSR_RECOG_RESULT.pDataResult, C.int(dataCnt)) l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> SelvySTT_GET_RES 인식 결과: %s", C.GoString(strresult)) defer C.free(unsafe.Pointer(strresult)) if resultLen > 0 { l.Printf("[LOG] sttselvas>SendSTTProcGetResult()> SelvySTT_GET_RES 인식 결과: 연속어 [ %s ], 첫음 [ %d ] 끝음 [ %d ] 스코어 [ %f ]", pResultStr, s.STTInfo.LVCSR_RECOG_RESULT.pDataResult.nStart, s.STTInfo.LVCSR_RECOG_RESULT.pDataResult.nEnd, s.STTInfo.LVCSR_RECOG_RESULT.fConfidScore) } else { return "", icserror.ICSERRSTTFail } // if dataCnt > 0 { // for i := 0; i < dataCnt; i++ { // l.Printf(icslog.LOG_LEVEL_INFO, -1, "음성인식 결과 : 인식어 [ %s ], 시작시간 [ %d ] 종료시간 [ %d ]", s.STTInfo.LVCSR_RECOG_RESULT.pDataResult[i].pTokenStr, s.STTInfo.LVCSR_RECOG_RESULT.pDataResult[i].nStart, s.STTInfo.LVCSR_RECOG_RESULT.pDataResult[i].nEnd) // } // } //s.GetSTTResultToStopSTT() // fmt.Print("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 // } returnstr := C.GoString(strresult) return returnstr, nil } return "", nil } func long(dataCnt int) { panic("unimplemented") } // func getResultMessage(result *C.LVCSR_RECOG_RESULT, size int) []string { // messages := make([]string, size) // for i := 0; i < size; i++ { // cMsg := C.GoString(result.pDataResult) // } // return s.rrData.GetAudio() // } func (s STTSelvas) GetAudio() []byte { return s.rrData.GetAudio() } func (s STTSelvas) GetReqTime() time.Time { return s.reqTime }