1
val asrAgent = nuguAndroidClient.asrAgent
Version
최신 버전은 1.7 입니다.
Version | Date | Description |
---|---|---|
1.0 | 2019.11.24 | 규격 추가 |
1.1 | 2020.04.29 | Recognize directive 에 wakeup, timeout 필드 추가 Recognize directive, ExpechSpeech event 에 asrContext 필드 추가 |
1.2 | 2020.06.05 | Recognize directive, ExpectSpeech event 의 asrContext 에 playServiceId 필드 추가 |
1.3 | 2020.06.09 | Recognize directive, ExpectSpeech event 의 sessionId 필드 삭제 |
1.4 | 2020.11.18 | ExpectSpeech directive 에 epd 필드 추가 |
1.5 | 2021.03.03 | Context 에 state, initiator 필드 추가 |
1.6 | 2021.05.31 | ASR.ExpectSpeech directive 에 listenTimeoutFailBeep 필드 추가 |
1.7 | 2022.07.04 | ASR.ExpectSpeech directive의 asrContext에 isAddListen 추가 |
State Diagram
SDK Interface
ASRAgent 사용
ASR interface 규격에 따른 디바이스의 동작 제어는 ASRAgent 가 처리합니다.
- Android
- iOS
- Linux
NuguAndroidClient instance 를 통해 ASRAgent instance 에 접근할 수 있습니다.
Microphone 으로 부터 음성 데이터를 가져오기 위한 AudioSourceManager 를 생성합니다.
1
val audioSourceManager = AudioSourceManager(AudioRecordSourceFactory())
음성인식에 필요한 학습 모델을 설정합니다.
1
2
3
4
5
6
7
8
9
10
11
12
NuguAndroidClient.Builder(
context,
NuguOAuth.create(context),
audioSourceManager
).endPointDetector(
EndPointDetector(
context.getDir(
"skt_nugu_assets",
Context.MODE_PRIVATE
).absolutePath + File.separator + "skt_epd_model.raw"
)
)
AudioSourceManager, ASRAgent 를 연결해주기 위한 SpeechRecognizerAggregator 를 생성합니다.
1
2
3
4
5
6
speechRecognizerAggregator = SpeechRecognizerAggregator(
null,
SpeechProcessorDelegate(asrAgent),
audioSourceManager,
Handler(Looper.getMainLooper())
)
NuguClient instance 를 통해 ASRAgent instance 에 접근할 수 있습니다.
1
let asrAgent = nuguClient.asrAgent
Microphone 으로 부터 음성 데이터를 가져오기 위한 MicInputProvider 를 생성합니다.
1
let micInputProvider = MicInputProvider()
Microphone 으로 부터 가져온 음성 데이터가 NuguClient 로 전달될 수 있도록 합니다.
1
micInputProvider.delegate = nuguClient
음성인식에 필요한 학습 모델을 설정합니다.
1
2
let epdFile = Bundle.main.url(forResource: "skt_epd_model", withExtension: "raw")!
nuguClient.asrAgent.options = ASROptions(endPointing: .client(epdFile: epdFile))
CapabilityFactory::makeCapability 함수로 ASRAgent 를 생성하고 NuguClient 에 추가해 주어야합니다.
1
2
3
4
5
6
auto asr_handler(std::shared_ptr<IASRHandler>(
CapabilityFactory::makeCapability<ASRAgent, IASRHandler>()));
nugu_client->getCapabilityBuilder()
->add(asr_handler.get())
->construct();
음성인식에 필요한 학습 모델을 설정합니다.
1
asr_handler->setAttribute(ASRAttribute { "/var/lib/nugu/model", "CLIENT", "PARTIAL" });
음성 인식 요청
아리아
발화 또는 NUGU Button 선택 시 Recognize event 를 전달하여 음성인식을 시작할 수 있습니다.
- Android
- iOS
- Linux
1
speechRecognizerAggregator.startListening(initiator = TAP)
1
2
try micInputProvider.start()
asrAgent.startRecognition(initiator: .user)
1
asr_handler->startRecognition()
음성인식 진행 상태 모니터링
음성인식에 대한 진행 상태를 모니터링 할 수 있습니다.
음성인식에 대한 STT(SpeechToText) 결과가 NotifyResult directive 로 전달됩니다.
- Android
- iOS
- Linux
SpeechRecognizerAggregatorInterface.OnStateChangeListener 를 추가합니다.
1
2
3
4
5
6
val listener = object: SpeechRecognizerAggregatorInterface.OnStateChangeListener {
override fun onStateChanged(state: State) {
...
}
}
speechRecognizerAggregator.addListener(listener)
ASRAgentInterface.OnResultListener 를 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
val resultListener = object: ASRAgentInterface.OnResultListener {
fun onPartialResult(result: String, dialogRequestId: String) {
// STT 중간 결과
...
}
fun onCompleteResult(result: String, dialogRequestId: String) {
// STT 최종 결과
...
}
...
}
asrAgent.addOnResultListener(resultListener)
ASRAgentDelegate 를 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
class MyASRAgentDelegate: ASRAgentDelegate {
func asrAgentDidChange(state: ASRState) {
...
}
func asrAgentDidReceive(result: ASRResult, dialogRequestId: String) {
// NotifyResult 결과 확인
...
}
}
asrAgent.add(delegate: MyASRAgentDelegate())
음성인식 진행 상태를 모니터링 하려면 IASRListener 를 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MyASRListener : public IASRListener {
public:
...
void onState(ASRState state, const std::string &dialog_id) override
{
...
}
void onPartial(const std::string &text, const std::string &dialog_id) override
{
// STT 중간 결과
...
}
void onComplete(const std::string &text, const std::string &dialog_id) override
{
// STT 최종 결과
...
}
...
};
auto asr_listener(std::make_shared<MyASRListener>());
CapabilityFactory::makeCapability<ASRAgent, IASRHandler>(asr_listener.get());
음성 인식 중단
사용자가 음성 인식 중단 요청을 StopRecognize event 로 전달할 수 있습니다.
- Android
- iOS
- Linux
1
speechRecognizerAggregator.stopListening()
1
asrAgent.stopRecognition()
1
asr_handler->stopRecognition()
Context
1
2
3
4
5
6
7
8
{
"ASR": {
"version": "1.6",
"engine": "{{STRING}}",
"state": "{{STRING}}",
"initiator": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
engine | string | N | Device 에서 사용하는 음성인식 engine 을 명시 NUGU 음성인식 engine 을 사용하는 경우 “skt”(값을 채우지 않으면 default “skt”) |
state | string | Y | IDLE EXPECTING_SPEECH LISTENING RECOGNIZING BUSY State Diagram 참고 |
initiator | string | N | 마이크 오픈이 어떻게 트리거되었는지 - WAKE_UP_WORD : 사용자 발화로 Wakeup - PRESS_AND_HOLD : PTT 방식으로 Wakeup - TAP : NUGU 버튼 등에 의해서 Wakeup - EXPECT_SPEECH : ASR.ExpectSpeech - EARSET : 이어셋 VoiceCommand 등을 통해 Wakeup |
Directives
ExpectSpeech
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"header": {
"namespace": "ASR",
"name": "ExpectSpeech",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"playServiceId": "{{STRING}}",
"domainTypes": ["{{STRING}}"],
"asrContext": {
"task": "{{STRING}}",
"sceneId": "{{STRING}}",
"sceneText": [
"{{STRING}}"
],
"playServiceId" : "playServiceId",
"isAddListen" : {{BOOLEAN}}
},
"epd": {
"timeoutMilliseconds": {{LONG}},
"silenceIntervalInMilliseconds": {{LONG}},
"maxSpeechDurationMilliseconds": {{LONG}}
},
"listenTimeoutFailBeep": {{BOOLEAN}}
}
}
parameter | type | mandatory | description |
---|---|---|---|
playServiceId | string | N |
Y : 회신받아야 하는 경우 N : 마이크만 열고 싶은경우 default : N |
property | string | N |
NORMAL : 일반 발화를 입력으로 받음 DICTATION : dictation 서버로 라우팅하여 처리 필드가 없는 경우 default 값은 NORMAL |
domainTypes | array of string | N | ExpectSpeech 의한 발화시에 NLU에서 사용할 domainType 셋팅 정보 |
asrContext | object | N | - |
asrContext.task | string | N | - |
asrContext.sceneId | string | N | - |
asrContext.sceneText | array of string | N | - |
asrContext.playServiceId | string | N | - |
asrContext.isAddListen | boolean | N | add-listen으로 인입된 발화 여부 |
epd | object | N | End Point Detection 관련 정보 없으면 device의 default 값을 사용 하위의 3개 파라미터도 optional이기 때문에 존재하는 파라미터만 업데이트하고, 없는 파라미터는 device의 default 값을 사용 |
epd.timeoutMilliseconds | long | N | Wake up 후 종료까지 대기 시간 (단위: msec) 이 값은 위의 timeoutInMilliseconds와는 다른 epd 전용값 |
epd.silenceIntervalInMilliseconds | long | N | end point detection 전에 기다리는 묵음 구간 (단위: msec) |
epd.maxSpeechDurationMilliseconds | long | N | 사용자 발화 최대 녹음 시간 (단위: msec) |
listenTimeoutFailBeep | boolean | N | Listening timeout 발생시 beep 재생 여부 default 값은 true |
NotifyResult
- 음성 인식 결과 전달
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"header": {
"namespace": "ASR",
"name": "NotifyResult",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"token": "{{STRING}}",
"result": "{{STRING}}",
"state": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
token | string | N | Recognize Event에서 사용한 token 값 (어떤 발화에 대한 분석 결과인지 식별하기 위한 용도) |
result | string | N | 인식 결과를 전송 |
state | string | Y |
PARTIAL : 사용자 발화의 일부분 COMPLETE : 사용자 발화의 전체 문장 NONE : 음성 인식 결과 없음 ERROR : Error 발생 SOS : SOS(Start of Speech) EOS : EOS(End of Speech) FA : Wakeup False Acceptance |
CancelRecognize
1
2
3
4
5
6
7
8
9
10
11
12
{
"header": {
"namespace": "ASR",
"name": "CancelRecognize",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"cause": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
cause | string | Y | WAKEUP_POWER : 다른 wakeup보다 power가 적어서 취소됨 |
Events
Recognize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"header": {
"namespace": "ASR",
"name": "Recognize",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"codec": "{{STRING}}",
"playServiceId": "{{STRING}}",
"domainTypes": ["{{STRING}}"],
"language": "{{STRING}}",
"endpointing": "{{STRING}}",
"encoding": "{{STRING}}",
"wakeup": {
"word": "{{STRING}}",
"boundary": {
"start": {{LONG}},
"end": {{LONG}},
"detection": {{LONG}}
},
"power": {
"noise": {{LONG}},
"speech": {{LONG}}
}
},
"asrContext": {
"task": "{{STRING}}",
"sceneId": "{{STRING}}",
"sceneText": [
"{{STRING}}"
],
"playServiceId" : "playServiceId"
},
"timeout": {
"listen": {{LONG}},
"maxSpeech": {{LONG}},
"response": {{LONG}}
}
}
}
parameter | type | mandatory | description |
---|---|---|---|
codec | string | Y | SPEEX |
playServiceId | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 playServiceId를 적용 |
property | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 property를 적용 |
domainTypes | array of string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 domainTypes를 적용 |
language | string | N |
KOR, ENG, JPN, CHN, … default 값은 KOR |
endpointing | string | Y |
CLIENT : 클라이언트 EPD(EndPointDetector) 사용 SERVER : 서버 EPD 사용 |
encoding | string | N |
PARTIAL : 사용자 발화의 일부분 COMPLETE : 사용자 발화의 전체 문장 (default) |
wakeup | object | N | 서버 EPD 사용시 필수 값. wakeup을 포함해서 서버에 전달하는 경우 포함 wakeup 정보를 전달하는 경우 포함 (전달하는 pcm에 wakeup이 포함되지 않더라도 필요한 경우 전달) |
wakeup.word | string | Y | 전송하는 stream에 포함된 wakeup word( ex “아리아”) |
wakeup.boundary | object | N | 전송하는 stream에서 wakeup word에 대한 boundary 정보 |
wakeup.boundary.start | long | Y | wakeup module 에서 얻은 milliseconds 를 sample count 로 변환해서 전송해야 함. sample count for start time |
wakeup.boundary.end | long | Y | wakeup module 에서 얻은 milliseconds 를 sample count 로 변환해서 전송해야 함. sample count for end time |
wakeup.boundary.detection | long | Y | wakeup module 에서 얻은 milliseconds 를 sample count 로 변환해서 전송해야 함. sample count for detection time |
wakeup.boundary.metric | string | N |
sample(default) / byte / frame / time 현재 sample 만 지원되며, 추후 byte / frame / time 속성 지원 예정 |
wakeup.power | object | N | 전송하는 stream에 포함된 wakeup pcm의 power값 |
wakeup.power.noise | float | Y | wakeup pcm의 power중 noise를 의미하는 값 (주로 min값) |
wakeup.power.speech | float | Y | wakeup pcm의 power중 speech를 의미하는 값 (주로 max값) |
asrContext | object | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 asrContext를 적용 |
asrContext.task | string | N | - |
asrContext.sceneId | string | N | - |
asrContext.sceneText | array of string | N | - |
asrContext.playServiceId | string | N | - |
timeout | object | N | Server EPD 사용시 필수 값. |
timeout.listen | long | Y | SOS 를 기다리는 시간 (milliseconds) |
timeout.maxSpeech | long | Y | SOS이후 EOS를 기다리는 시간 (milliseconds) |
timeout.response | long | Y | EOS 이후 응답을 기다리는 시간 (milliseconds) |
ResponseTimeout
- Recognize Event가 전달되고 사용자 발화도 모두 전달이 완료된 이후 응답을 받지 못한 경우
1
2
3
4
5
6
7
8
9
10
11
12
{
"header": {
"namespace": "ASR",
"name": "ResponseTimeout",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"playServiceId": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
playServiceId | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 playServiceId를 적용 |
ListenTimeout
- Recognize event가 전달되고 사용자 발화가 발화하지 않은 경우
1
2
3
4
5
6
7
8
9
10
11
12
{
"header": {
"namespace": "ASR",
"name": "ListenTimeout",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"playServiceId": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
playServiceId | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 playServiceId를 적용 |
StopRecognize
- Recognize event 취소
1
2
3
4
5
6
7
8
9
10
11
12
{
"header": {
"namespace": "ASR",
"name": "StopRecognize",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"playServiceId": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
playServiceId | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 playServiceId를 적용 |
ListenFailed
- Recognize event 이후 클라이언트에서 에러(마이크를 열지 못하는 등)가 발생한 경우
1
2
3
4
5
6
7
8
9
10
11
12
{
"header": {
"namespace": "ASR",
"name": "ListenFailed",
"messageId": "{{STRING}}",
"dialogRequestId": "{{STRING}}",
"version": "1.6"
},
"payload": {
"playServiceId": "{{STRING}}"
}
}
parameter | type | mandatory | description |
---|---|---|---|
playServiceId | string | N | ExpectSpeech에 의한 발화인 경우에만 ExpectSpeech에서 받은 playServiceId를 적용 |