icsstt 모듈 빠져있던것 추가
parent
095ac40fa3
commit
d2bac81363
@ -0,0 +1,180 @@
|
|||||||
|
package stt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"mybatch/icslog"
|
||||||
|
)
|
||||||
|
|
||||||
|
const RR_200MSEC_SIZE = 3200
|
||||||
|
|
||||||
|
type RRData struct {
|
||||||
|
wPos int
|
||||||
|
wTPos int
|
||||||
|
wtSize int
|
||||||
|
rPos int
|
||||||
|
size int // max size
|
||||||
|
audio []byte
|
||||||
|
rtAudio []byte //for GetAudio()
|
||||||
|
rtAudioLen int
|
||||||
|
m *sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRRData(size int) *RRData {
|
||||||
|
if size <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
rr := RRData{wPos: 0, rPos: 0, size: size, rtAudioLen: 0}
|
||||||
|
rr.m = &sync.Mutex{}
|
||||||
|
rr.audio = make([]byte, size)
|
||||||
|
rr.rtAudio = make([]byte, size)
|
||||||
|
|
||||||
|
return &rr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) AddAudio(data []byte) int {
|
||||||
|
l := icslog.InitializeLogger()
|
||||||
|
|
||||||
|
size := len(data)
|
||||||
|
if size <= 0 || rr.audio == nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Lock()
|
||||||
|
if rr.wPos == 0 && rr.wTPos != 0 {
|
||||||
|
rr.wPos = rr.wtSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if rr.wPos+size > rr.size {
|
||||||
|
l.Printf("AddAudio> RRData write size exceeded!!! size: %d-%d", rr.size, rr.wPos+size)
|
||||||
|
rr.wPos = rr.wtSize
|
||||||
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "AddAudio> RRData write size exceeded. wPos reset. %d-%d-%d", rr.wPos, rr.size, rr.wPos+size)
|
||||||
|
}
|
||||||
|
|
||||||
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "AddAudio> wPos: %d, size: %d, total size: %d", rr.wPos, size, rr.size)
|
||||||
|
|
||||||
|
copy(rr.audio[rr.wPos:], data[:])
|
||||||
|
rr.wPos += size
|
||||||
|
|
||||||
|
if rr.size <= rr.rtAudioLen {
|
||||||
|
rr.rtAudio = append(rr.rtAudio, data...)
|
||||||
|
} else {
|
||||||
|
copy(rr.rtAudio[rr.rtAudioLen:], data)
|
||||||
|
}
|
||||||
|
rr.rtAudioLen += size
|
||||||
|
|
||||||
|
rr.m.Unlock()
|
||||||
|
|
||||||
|
return rr.wPos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) AddTempAudio(data []byte) int {
|
||||||
|
//1sec temp buffer
|
||||||
|
if rr.size < 40000 || rr.audio == nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
size := len(data)
|
||||||
|
if size <= 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Lock()
|
||||||
|
|
||||||
|
//l := icslog.GetIcsLog()
|
||||||
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "AddTempAudio> wtPos: %d, size: %d", rr.wTPos, size)
|
||||||
|
|
||||||
|
if rr.wTPos+size > 40000 {
|
||||||
|
//rr.wTPos = 0
|
||||||
|
rr.wtSize = 40000
|
||||||
|
rr.audio = rr.audio[size:]
|
||||||
|
copy(rr.audio[rr.wTPos-size:], data[:])
|
||||||
|
} else {
|
||||||
|
rr.wtSize += size
|
||||||
|
copy(rr.audio[rr.wTPos:], data[:])
|
||||||
|
rr.wTPos += size
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Unlock()
|
||||||
|
|
||||||
|
return rr.wTPos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) ReadAudio(size int) (int, []byte) {
|
||||||
|
l := icslog.InitializeLogger()
|
||||||
|
|
||||||
|
if rr.audio == nil {
|
||||||
|
return -2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Lock()
|
||||||
|
if int(math.Abs(float64(rr.wPos-rr.rPos))) < 1600 || int(math.Abs(float64(rr.wPos-rr.rPos))) < size {
|
||||||
|
rr.m.Unlock()
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
rData := make([]byte, size)
|
||||||
|
|
||||||
|
if rr.size < rr.rPos+size {
|
||||||
|
rr.m.Unlock()
|
||||||
|
l.Printf("ReadAudio> RRData read size exceeded!!! size: %d-%d", rr.size, rr.rPos+size)
|
||||||
|
return -1, nil
|
||||||
|
//rr.rPos = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "ReadAudio> rPos: %d, size: %d, total size: %d", rr.rPos, size, rr.size)
|
||||||
|
|
||||||
|
copy(rData[:], rr.audio[rr.rPos:rr.rPos+size])
|
||||||
|
//fmt.Println("read audio data:", rr.rPos)
|
||||||
|
rr.rPos += size
|
||||||
|
|
||||||
|
rr.m.Unlock()
|
||||||
|
|
||||||
|
return rr.rPos, rData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) Clear() {
|
||||||
|
rr.m.Lock()
|
||||||
|
rr.wPos = 0
|
||||||
|
rr.rPos = 0
|
||||||
|
rr.audio = nil
|
||||||
|
rr.rtAudio = nil
|
||||||
|
rr.m.Unlock()
|
||||||
|
|
||||||
|
l := icslog.InitializeLogger()
|
||||||
|
l.Print("Cleared RRData")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) GetAudio() []byte {
|
||||||
|
if rr.audio == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Lock()
|
||||||
|
|
||||||
|
if rr.rtAudioLen <= 0 {
|
||||||
|
rr.m.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "GetAudio> audio length: %d", rr.rtAudioLen)
|
||||||
|
|
||||||
|
var rData []byte
|
||||||
|
if rr.wtSize > 0 {
|
||||||
|
rData = make([]byte, rr.wtSize+rr.rtAudioLen)
|
||||||
|
copy(rData, rr.audio[:rr.wtSize])
|
||||||
|
copy(rData[rr.wtSize:], rr.rtAudio)
|
||||||
|
} else {
|
||||||
|
rData = make([]byte, rr.rtAudioLen)
|
||||||
|
copy(rData, rr.rtAudio)
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.m.Unlock()
|
||||||
|
|
||||||
|
return rData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *RRData) Close() {
|
||||||
|
rr.audio = nil
|
||||||
|
rr.rtAudio = nil
|
||||||
|
//rr = new(RRData)
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package stt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cloud.google.com/go/speech/apiv1"
|
||||||
|
"cloud.google.com/go/speech/apiv1/speechpb"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RecognizeSpeech(language, filepath string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
client, err := speech.NewClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
audioData, err := os.ReadFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &speechpb.RecognizeRequest{
|
||||||
|
Config: &speechpb.RecognitionConfig{
|
||||||
|
Encoding: speechpb.RecognitionConfig_LINEAR16,
|
||||||
|
SampleRateHertz: 16000,
|
||||||
|
LanguageCode: language,
|
||||||
|
},
|
||||||
|
Audio: &speechpb.RecognitionAudio{
|
||||||
|
AudioSource: &speechpb.RecognitionAudio_Content{
|
||||||
|
Content: audioData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Recognize(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, result := range resp.Results {
|
||||||
|
for _, alt := range result.Alternatives {
|
||||||
|
log.Printf("Transcript: %s\n", alt.Transcript)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package stt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mybatch/icsconf"
|
||||||
|
"mybatch/icserror"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var config icsconf.AppInfo
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config = icsconf.Getconfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXXX(t *testing.T) {
|
||||||
|
data, _ := os.ReadFile("/home/prac/svc/icsbc/voice/pcm/20250913223412/20250913223412-left.pcm")
|
||||||
|
connectSttServer()
|
||||||
|
sttResTest(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectSttServer(voicedata []byte) (bool, *icserror.IcsError) {
|
||||||
|
var s *STTSelvas
|
||||||
|
var sttErr *icserror.IcsError
|
||||||
|
ip := config.STT.SrcIP
|
||||||
|
port, _ := strconv.Atoi(cfg.STT.Port)
|
||||||
|
callId := "00ef1234567899001"
|
||||||
|
custid := "3002"
|
||||||
|
RecordFilePath := "/home/prac/svc/icsbc/sttres"
|
||||||
|
|
||||||
|
// func NewSTTS(sid int, IP string, port int, callID string, custID string, filePath string)
|
||||||
|
s, sttErr = NewSTTS(ip, port, callId, custid, RecordFilePath)
|
||||||
|
if sttErr != nil {
|
||||||
|
return false, icserror.ICSERRSTTConnectFail
|
||||||
|
} else if s != nil {
|
||||||
|
fmt.Println("STT session:", s)
|
||||||
|
}
|
||||||
|
fmt.Println("stt server is connected with: ", ip, ", port: ", port)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
func sttResTest(voicedata []byte) (bool, *icserror.IcsError) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,449 @@
|
|||||||
|
package stt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"mybatch/icsconf"
|
||||||
|
encry "mybatch/icsencry"
|
||||||
|
"mybatch/icserror"
|
||||||
|
httprequest "mybatch/icshttp"
|
||||||
|
"mybatch/icslog"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestData struct {
|
||||||
|
StartTime string `json:"starttime"`
|
||||||
|
Ext string `json:"ext"`
|
||||||
|
ConnID string `json:"connid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileListResponse struct {
|
||||||
|
TotalCnt string `json:"totalCnt"`
|
||||||
|
ReturnCode string `json:"returnCode"`
|
||||||
|
ReturnMsg string `json:"returnMsg"`
|
||||||
|
List []FileInfo `json:"list"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileInfo struct {
|
||||||
|
No int `json:"no"`
|
||||||
|
ConnID string `json:"connid"`
|
||||||
|
Ext string `json:"ext"`
|
||||||
|
StartTime string `json:"starttime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Transcript struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
StartTime int `json:"startTime"`
|
||||||
|
EndTime int `json:"endTime"`
|
||||||
|
EndPoint bool `json:"endPoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseData struct {
|
||||||
|
Uid string `json:"uid"`
|
||||||
|
Ext string `json:"ext"`
|
||||||
|
SpeakerTag string `json:"speakerTag"`
|
||||||
|
Transcripts []Transcript `json:"transcripts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TAMessage struct {
|
||||||
|
Cmd string `json:"cmd"` // STT 이벤트 상태 구분값 S:시작, E:종료, T:Text, P:Partial
|
||||||
|
ConnID string `json:"connid"` //Cti 생성콜 key
|
||||||
|
Tel string `json:"tel"` //고객 전화번호
|
||||||
|
Ext string `json:"ext"` //상담사 내선번호
|
||||||
|
CallStartTime string `json:"callStartTime"` //콜 시작시간 unixtime
|
||||||
|
IgGbn string `json:"igGbn"` //통화유형 0:알수없음, 1:인바운드, 2:아웃바운드
|
||||||
|
DateTime string `json:"datetime"` //STT 시작시간
|
||||||
|
Stt string `json:"stt"` //STT 결과
|
||||||
|
Dir string `json:"dir"` //STT 화자구분 R:고객, T:상담사
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfg icsconf.AppInfo
|
||||||
|
l *log.Logger
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cfg = icsconf.Getconfig()
|
||||||
|
l = icslog.InitializeLogger()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProcessPostRequestForDataList() {
|
||||||
|
var starttime uint64
|
||||||
|
currentDate := time.Now().Format("20060102")
|
||||||
|
currentDateUint64, _ := strconv.ParseUint(currentDate, 10, 64)
|
||||||
|
|
||||||
|
starttime = currentDateUint64 - 1
|
||||||
|
starttimeStr := strconv.FormatUint(starttime, 10)
|
||||||
|
|
||||||
|
data := RequestData{
|
||||||
|
StartTime: starttimeStr,
|
||||||
|
Ext: "",
|
||||||
|
ConnID: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, _ := json.Marshal(data)
|
||||||
|
encryptedRequestBody := encry.Encrypting(jsonData)
|
||||||
|
|
||||||
|
url := "https://192.168.0.69:8080/sttRest.do"
|
||||||
|
method := "POST"
|
||||||
|
requestBody := fmt.Sprintf(`{"data":"%s"}`, encryptedRequestBody)
|
||||||
|
|
||||||
|
response, err := httprequest.HttpRequest(url, method, requestBody)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("error occured while requesting http post for datalist:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer response.Body.Close()
|
||||||
|
body, _ := io.ReadAll(response.Body)
|
||||||
|
|
||||||
|
fmt.Println("응답 on ProcessPostRequestForDataList: ", string(body))
|
||||||
|
|
||||||
|
var parsedRes FileListResponse
|
||||||
|
if err := json.Unmarshal([]byte(body), &parsedRes); err != nil {
|
||||||
|
l.Println("Error parsing JSON:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqDataForVoiceFile RequestData
|
||||||
|
if len(parsedRes.List) > 0 {
|
||||||
|
for _, item := range parsedRes.List {
|
||||||
|
reqDataForVoiceFile = RequestData{
|
||||||
|
StartTime: item.StartTime,
|
||||||
|
Ext: item.Ext,
|
||||||
|
ConnID: item.ConnID,
|
||||||
|
}
|
||||||
|
// Requesting For wav file and download it at local
|
||||||
|
postReqForWavFileAndDownload(reqDataForVoiceFile)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
l.Println("No items in the datalist.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func postReqForWavFileAndDownload(parsedRes RequestData) {
|
||||||
|
jsonData, _ := json.Marshal(parsedRes)
|
||||||
|
encryptedRequestBody := encry.Encrypting(jsonData)
|
||||||
|
|
||||||
|
url := "https://192.168.0.69:8080/sttRest.do"
|
||||||
|
method := "POST"
|
||||||
|
requestBody := fmt.Sprintf(`{"data":"%s"}`, encryptedRequestBody)
|
||||||
|
|
||||||
|
response, err := httprequest.HttpRequest(url, method, requestBody)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("error occured while requesting http post for datalist:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
st := parsedRes.StartTime
|
||||||
|
wavFilePath := cfg.Directories.WAVDirectory
|
||||||
|
fileName := fmt.Sprintf(`%s/%s.wav`, wavFilePath, st)
|
||||||
|
file, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("error occured while creating file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, response.Body)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("error occured while writing to file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 잘 쪼개졌다면 각 left, right을 stt 돌리기
|
||||||
|
pcmResult, folderName := devideWavTo2Pcm(fileName)
|
||||||
|
|
||||||
|
if pcmResult {
|
||||||
|
sttCallRes, err := controlSTT(parsedRes, folderName)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("runSTT() failed with the error: ", err)
|
||||||
|
}
|
||||||
|
// stt 콜이 성공이라면 pcm 파일 지우기
|
||||||
|
if sttCallRes {
|
||||||
|
pcmDir := filepath.Join(cfg.Directories.PCMDirectory, st)
|
||||||
|
deletePcmFolder(pcmDir)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deletePcmFolder(foldername string) (bool, *icserror.IcsError) {
|
||||||
|
fmt.Println("foldername in deletePcmFolder func: ", foldername)
|
||||||
|
if _, err := os.Stat(foldername); os.IsNotExist(err) {
|
||||||
|
l.Println("pcm folder does not exist with the dir: ", foldername) //error here
|
||||||
|
l.Println("error: ", err)
|
||||||
|
return false, icserror.ICSERRFileOpen
|
||||||
|
}
|
||||||
|
err := os.RemoveAll(foldername)
|
||||||
|
if err != nil {
|
||||||
|
l.Panicln("error occured while deleting folder: ", foldername)
|
||||||
|
return false, icserror.ICSERRWriteFile
|
||||||
|
}
|
||||||
|
l.Printf(`folder: %s has been successfully deleted`, foldername)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func devideWavTo2Pcm(fileName string) (result bool, folderName string) {
|
||||||
|
// fileName: /home/prac/svc/icsbc/voice/wav/20250913223412.wav
|
||||||
|
fileNameWithoutWav := fileName[:len(fileName)-4]
|
||||||
|
lastSlashIdx := strings.LastIndex(fileNameWithoutWav, "/")
|
||||||
|
starttime := fileNameWithoutWav[lastSlashIdx+1:] //starttime: 20250913223412
|
||||||
|
pcmDir := cfg.Directories.PCMDirectory
|
||||||
|
|
||||||
|
starttimeDir := fmt.Sprintf("%s/%s", pcmDir, starttime)
|
||||||
|
os.MkdirAll(starttimeDir, os.ModePerm)
|
||||||
|
|
||||||
|
leftOutputFile := fmt.Sprintf(`%s/%s-left.pcm`, starttimeDir, starttime)
|
||||||
|
rightOutputFile := fmt.Sprintf(`%s/%s-right.pcm`, starttimeDir, starttime)
|
||||||
|
fmt.Println("inFile reading wav path: ", fileName)
|
||||||
|
|
||||||
|
inFile, err := os.Open(fileName)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("failed to open input file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
defer inFile.Close()
|
||||||
|
|
||||||
|
leftFile, err := os.Create(leftOutputFile)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("failed to create left channel file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
defer leftFile.Close()
|
||||||
|
|
||||||
|
rightFile, err := os.Create(rightOutputFile)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("failed to create right channel file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
defer rightFile.Close()
|
||||||
|
|
||||||
|
// Skip WAV header (44 bytes)
|
||||||
|
wavHeader := make([]byte, 44)
|
||||||
|
if _, err := inFile.Read(wavHeader); err != nil {
|
||||||
|
l.Println("failed to read WAV header: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a valid WAV file
|
||||||
|
if string(wavHeader[:4]) != "RIFF" || string(wavHeader[8:12]) != "WAVE" {
|
||||||
|
l.Println("invalid WAV file format")
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if WAV file is stereo
|
||||||
|
numChannels := binary.LittleEndian.Uint16(wavHeader[22:24])
|
||||||
|
if numChannels != 2 {
|
||||||
|
l.Println("unsupported channel count: this function only supports stereo (2 channels)")
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, 4) // 2 bytes per sample * 2 channels
|
||||||
|
|
||||||
|
for {
|
||||||
|
n, err := inFile.Read(buf)
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
l.Println("failed to read from input file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if n < 4 {
|
||||||
|
l.Printf("unexpected sample size read: %d\n", n)
|
||||||
|
// Break or handle the case based on your needs
|
||||||
|
for i := n; i < 4; i++ {
|
||||||
|
buf[i] = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
leftSample := buf[:2]
|
||||||
|
rightSample := buf[2:]
|
||||||
|
|
||||||
|
if err := binary.Write(leftFile, binary.LittleEndian, leftSample); err != nil {
|
||||||
|
l.Println("failed to write to left channel file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := binary.Write(rightFile, binary.LittleEndian, rightSample); err != nil {
|
||||||
|
l.Println("failed to write to right channel file: %v", err)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Println("WAV file split successfully")
|
||||||
|
return true, starttime
|
||||||
|
}
|
||||||
|
|
||||||
|
// server 연결, stt 호출, 연결 해제
|
||||||
|
func controlSTT(parsedRes RequestData, folderName string) (bool, *icserror.IcsError) {
|
||||||
|
pcmDirectory := cfg.Directories.PCMDirectory
|
||||||
|
pcmDirectory = filepath.Join(pcmDirectory, folderName)
|
||||||
|
|
||||||
|
// walking the file that has each left and right pcm files
|
||||||
|
filepath.Walk(pcmDirectory, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
l.Println("Error occured while walking pcm folder. error: ", err)
|
||||||
|
l.Println("The pcm file path: ", pcmDirectory)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.IsDir() && filepath.Ext(path) == "left.pcm" {
|
||||||
|
stterr := connectSelvasServerRunSTT(parsedRes, path, "left")
|
||||||
|
if stterr != nil {
|
||||||
|
l.Println("Error occured on recognizeSpeechFromPcmFile(). error: ", stterr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !info.IsDir() && filepath.Ext(path) == "right.pcm" {
|
||||||
|
stterr := connectSelvasServerRunSTT(parsedRes, path, "right")
|
||||||
|
if stterr != nil {
|
||||||
|
l.Println("Error occured on recognizeSpeechFromPcmFile(). error: ", stterr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectSelvasServerRunSTT(parsedRes RequestData, filePath string, leftright string) *icserror.IcsError {
|
||||||
|
var sttRes NewSTTResult
|
||||||
|
var sttErr *icserror.IcsError
|
||||||
|
|
||||||
|
voicedata, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return icserror.ICSERRCONFOpenFile
|
||||||
|
}
|
||||||
|
ip := cfg.STT.SrcIP
|
||||||
|
port, _ := strconv.Atoi(cfg.STT.Port)
|
||||||
|
callId := parsedRes.ConnID
|
||||||
|
custId := parsedRes.Ext
|
||||||
|
recordFilePath := cfg.Directories.RecDirectory
|
||||||
|
|
||||||
|
// connecting with STT server
|
||||||
|
s, sttErr := NewSTTS(ip, port, callId, custId, recordFilePath)
|
||||||
|
if sttErr != nil {
|
||||||
|
return icserror.ICSERRSTTConnectFail
|
||||||
|
} else if s != nil {
|
||||||
|
fmt.Println("STT session:", s)
|
||||||
|
}
|
||||||
|
l.Println("STT server is connected with: ", ip, ", port: ", port)
|
||||||
|
|
||||||
|
// STT 호출
|
||||||
|
sttRes, sttErr = s.SendSTT(voicedata, true, nil)
|
||||||
|
if sttErr != nil {
|
||||||
|
l.Println("calling sendSTT() on sttselvas.go has failed with error: ", sttErr)
|
||||||
|
return icserror.ICSERRSTTSendFail
|
||||||
|
}
|
||||||
|
|
||||||
|
// STT server and chanel close
|
||||||
|
s.CloseChanelAndServer()
|
||||||
|
|
||||||
|
// STT 호출 성공시 결과를 websocket, ta rest로 송신
|
||||||
|
if sttRes.Res != "" {
|
||||||
|
wssres, wsserr := webSocketSend(parsedRes, sttRes, leftright)
|
||||||
|
httpres, httperr := taRestSend(parsedRes, sttRes, s.GetReqTime(), leftright)
|
||||||
|
if wssres && httpres {
|
||||||
|
l.Println("stt results have successfully sent through both wss and http(ta)")
|
||||||
|
}
|
||||||
|
if wsserr != nil {
|
||||||
|
l.Println("sending stt result through websocket has failed with the error: ", wsserr)
|
||||||
|
}
|
||||||
|
if httperr != nil {
|
||||||
|
l.Println("sending stt result through http for ta has failed with the error: ", httperr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func webSocketSend(parsedRes RequestData, sttRes NewSTTResult, leftright string) (bool, *icserror.IcsError) {
|
||||||
|
speaker := "X" // T: 상담사
|
||||||
|
if leftright == "left" {
|
||||||
|
speaker = "R" //R: 고객
|
||||||
|
}
|
||||||
|
url := "ws://192.168.0.69:8090/wss"
|
||||||
|
headers := http.Header{
|
||||||
|
"Origin": {"https://192.168.0.69"},
|
||||||
|
}
|
||||||
|
conn, _, err := websocket.DefaultDialer.Dial(url, headers)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("Failed to connect to WebSocket: %v", err)
|
||||||
|
return false, icserror.ICSERRWEBSOCKETConnectFailError
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
resData := ResponseData{
|
||||||
|
Uid: parsedRes.ConnID,
|
||||||
|
Ext: parsedRes.Ext,
|
||||||
|
SpeakerTag: speaker,
|
||||||
|
Transcripts: []Transcript{
|
||||||
|
{
|
||||||
|
Text: sttRes.Res,
|
||||||
|
StartTime: sttRes.NStart,
|
||||||
|
EndTime: sttRes.NEnd,
|
||||||
|
EndPoint: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, _ := json.Marshal(resData)
|
||||||
|
encryptedResponseBody := encry.Encrypting(jsonData)
|
||||||
|
|
||||||
|
responseBody := fmt.Sprintf(`{"data":"%s"}`, encryptedResponseBody)
|
||||||
|
|
||||||
|
err = conn.WriteMessage(websocket.TextMessage, []byte(responseBody))
|
||||||
|
if err != nil {
|
||||||
|
l.Println("failed to send msg via websocket with the err: ", err)
|
||||||
|
return false, icserror.ICSERRWEBSOCKETWriteError
|
||||||
|
} else {
|
||||||
|
l.Println("Sent the msg via websocket. message body: ", responseBody)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func taRestSend(parsedRes RequestData, sttRes NewSTTResult, reqTime time.Time, leftright string) (bool, *icserror.IcsError) {
|
||||||
|
dir := "T" // T: 상담사
|
||||||
|
if leftright == "left" {
|
||||||
|
dir = "R" //R: 고객
|
||||||
|
}
|
||||||
|
resData := TAMessage{
|
||||||
|
Cmd: "T",
|
||||||
|
ConnID: parsedRes.ConnID,
|
||||||
|
Tel: "", // 정보없음
|
||||||
|
Ext: parsedRes.Ext,
|
||||||
|
CallStartTime: parsedRes.StartTime,
|
||||||
|
IgGbn: "1", // 인바운드
|
||||||
|
DateTime: reqTime.Format("2006-01-02 15:04:05"),
|
||||||
|
Stt: sttRes.Res,
|
||||||
|
Dir: dir,
|
||||||
|
}
|
||||||
|
jsonData, _ := json.Marshal(resData)
|
||||||
|
encryptedRequestBody := encry.Encrypting(jsonData)
|
||||||
|
|
||||||
|
url := "https://192.168.0.69:8080/taRest.do"
|
||||||
|
method := "POST"
|
||||||
|
requestBody := fmt.Sprintf(`{"data":"%s"}`, encryptedRequestBody)
|
||||||
|
|
||||||
|
response, err := httprequest.HttpRequest(url, method, requestBody)
|
||||||
|
if err != nil {
|
||||||
|
l.Println("error occured while requesting http post for datalist:", err)
|
||||||
|
return false, icserror.ICSERRHTTPClientExcecution
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Println("TA msg has been successfully sent. response: ", response)
|
||||||
|
return true, nil
|
||||||
|
}
|
@ -0,0 +1,727 @@
|
|||||||
|
//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
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue