Skip to content

Commit 3b69c0b

Browse files
kifirdahrosa
authored andcommitted
Merged in alexander_nikiforov/telscale-media-server-asr/dtmf_speech (pull request #24)
Combinef "DTMF+speech" mode is implemented Approved-by: Henrique Rosa <henrique.rosa@telestax.com>
2 parents a87ef9a + d25e563 commit 3b69c0b

10 files changed

Lines changed: 886 additions & 38 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[plantuml,file="mgcp-asr-dtmf-state.png"]
2+
--
3+
state AsrSignal {
4+
[*] --> LoadingPlaylist
5+
LoadingPlaylist --> Prompting : prompt
6+
LoadingPlaylist --> Prompted : no_prompt
7+
Prompting --> Prompted : end_prompt
8+
Prompting --> Prompting : next_track
9+
Prompted --> [*]
10+
||
11+
[*] --> Collecting
12+
Collecting --> Collecting : recognized_text
13+
Collecting --> WaitingAsrTimeout: end_input (eik, mrt, pst)
14+
Collecting --> DigitsCollecting: digit
15+
DigitsCollecting --> Collected : digits_collected, end_input (eik, mrt, pst)
16+
DigitsCollecting --> DigitsCollecting: digit
17+
WaitingAsrTimeout --> Collected: asr_timeout
18+
WaitingAsrTimeout --> WaitingAsrTimeout : recognized_text
19+
Collected --> [*]
20+
}
21+
22+
[*] -down-> AsrSignal
23+
AsrSignal -down-> Evaluating : evaluate/timeout
24+
AsrSignal --> Canceled : cancel
25+
26+
Evaluating -down-> Failing : no_recognized_text
27+
Evaluating -down-> Canceled : cancel
28+
Evaluating -down-> Succeeding : succeed
29+
30+
Failing -down-> PlayingFailure : prompt
31+
Failing -down-> Failed : no_prompt/cancel
32+
PlayingFailure --> PlayingFailure : next_track
33+
PlayingFailure -down-> Failed : end_prompt/cancel
34+
35+
Succeeding -down-> PlayingSuccess : prompt
36+
Succeeding -down-> Succeeded : no_prompt/cancel
37+
PlayingSuccess --> PlayingSuccess : next_track
38+
PlayingSuccess -down-> Succeeded : end_prompt/cancel
39+
40+
Canceled -down-> Succeeded : succeed
41+
Canceled -down-> Failed : fail (NO_SPEECH)
42+
43+
Succeeded --> [*]
44+
Failed --> [*]
45+
--

controls/mgcp2/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@
7979
<version>0.3.9.11</version>
8080
</dependency>
8181
<dependency>
82-
<groupId>org.snmp4j</groupId>
83-
<artifactId>snmp4j</artifactId>
84-
<version>2.5.6</version>
82+
<groupId>commons-codec</groupId>
83+
<artifactId>commons-codec</artifactId>
84+
<version>1.10</version>
8585
</dependency>
8686
</dependencies>
8787

controls/mgcp2/src/main/java/org/mobicents/media/control/mgcp/pkg/au/SignalParameters.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ public enum SignalParameters {
7272
MAXIMUM_RECOGNITION_TIME("mrt"),
7373
DRIVER("dr"),
7474
HOT_WORDS("hw"),
75-
LANG("ln")
75+
LANG("ln"),
76+
INPUT("in")
7677
;
7778

7879
private final String symbol;

controls/mgcp2/src/main/java/org/mobicents/media/control/mgcp/pkg/au/asr/AsrContext.java

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
package org.mobicents.media.control.mgcp.pkg.au.asr;
2323

24+
import com.google.common.base.Optional;
2425
import org.mobicents.media.control.mgcp.pkg.au.Playlist;
2526

2627
import java.util.Arrays;
@@ -32,6 +33,7 @@
3233
public class AsrContext {
3334

3435
public static final char NO_DTMF_TONE = ' ';
36+
private static final String MIXED_INPUT_TYPE = "DTMF SPEECH";
3537

3638
// Playlists
3739
private final Playlist initialPrompt;
@@ -41,6 +43,9 @@ public class AsrContext {
4143
private final Parameters params;
4244

4345
// Runtime data
46+
private boolean digitsOnlyMode = false;
47+
private final StringBuilder collectedDigits;
48+
private long lastCollectedDigitOn;
4449
private char lastTone;
4550
private int returnCode;
4651
private String recognizedText;
@@ -55,6 +60,8 @@ public AsrContext(Parameters params) {
5560
this.successAnnouncement = new Playlist(params.getSuccessAnnouncementSegments(), 1);
5661

5762
// Runtime Data
63+
this.collectedDigits = new StringBuilder("");
64+
this.lastCollectedDigitOn = 0L;
5865
this.lastTone = NO_DTMF_TONE;
5966
this.returnCode = 0;
6067
}
@@ -63,6 +70,14 @@ public Parameters getParams() {
6370
return params;
6471
}
6572

73+
public boolean isMixedInputSupported() {
74+
return MIXED_INPUT_TYPE.equalsIgnoreCase(params.getInputType());
75+
}
76+
77+
public boolean isDigitsOnlyMode() {
78+
return digitsOnlyMode;
79+
}
80+
6681
public Playlist getInitialPrompt() {
6782
return initialPrompt;
6883
}
@@ -75,9 +90,72 @@ public Playlist getSuccessAnnouncement() {
7590
return successAnnouncement;
7691
}
7792

93+
/**
94+
* The minimum number of digits to collect.
95+
* <p>
96+
* <b>Defaults to one.</b> This parameter should not be specified if the Digit Pattern parameter is present.
97+
* </p>
98+
*
99+
* @return
100+
*/
101+
public int getMinimumNumDigits() {
102+
return params.getMinimumNumDigits();
103+
}
104+
105+
/**
106+
* The maximum number of digits to collect.
107+
* <p>
108+
* <b>Defaults to one.</b> This parameter should not be specified if the Digit Pattern parameter is present.
109+
* </p>
110+
*
111+
* @return
112+
*/
113+
public int getMaximumNumDigits() {
114+
return params.getMaximumNumDigits();
115+
}
116+
117+
/**
118+
* A legal digit map as described in <a href="https://tools.ietf.org/html/rfc2885#section-7.1.14">section 7.1.14</a> of the
119+
* MEGACO protocol using the DTMF mappings associated with the Megaco DTMF Detection Package described in the Megaco
120+
* protocol document.
121+
* <p>
122+
* <b>This parameter should not be specified if one or both of the Minimum # Of Digits parameter and the Maximum Number Of
123+
* Digits parameter is present.</b>
124+
* </p>
125+
*
126+
* @return The digit pattern or an empty String if not specified.
127+
*/
128+
public String getDigitPattern() {
129+
return params.getDigitPattern();
130+
}
131+
132+
public boolean hasDigitPattern() {
133+
return !Optional.fromNullable(params.getDigitPattern()).or("").isEmpty();
134+
}
135+
78136
/*
79137
* Runtime Data
80138
*/
139+
public void collectDigit(char digit) {
140+
if (isMixedInputSupported()) {
141+
this.digitsOnlyMode = true;
142+
this.collectedDigits.append(digit);
143+
this.lastCollectedDigitOn = System.currentTimeMillis();
144+
}
145+
}
146+
147+
public String getCollectedDigits() {
148+
return collectedDigits.toString();
149+
}
150+
151+
public int countCollectedDigits() {
152+
return collectedDigits.length();
153+
}
154+
155+
public long getLastCollectedDigitOn() {
156+
return lastCollectedDigitOn;
157+
}
158+
81159
public char getLastTone() {
82160
return lastTone;
83161
}
@@ -116,7 +194,11 @@ public static class Parameters {
116194
private final List<String> hotWords;
117195
private final int waitingTimeForInput;
118196
private final int postSpeechTimer;
197+
private final int minimumNumDigits;
198+
private final int maximumNumDigits;
199+
private final String digitPattern;
119200
private final String lang;
201+
private final String inputType;
120202

121203
public Parameters(String[] initialPromptParam,
122204
String[] failureAnnSegments,
@@ -127,7 +209,11 @@ public Parameters(String[] initialPromptParam,
127209
final List<String> hotWords,
128210
final int waitingTimeForInput,
129211
final int postSpeechTimer,
130-
final String lang) {
212+
final int minimumNumDigits,
213+
final int maximumNumDigits,
214+
final String digitPattern,
215+
final String lang,
216+
final String inputType) {
131217
this.initialPromptParam = initialPromptParam;
132218
this.failureAnnSegments = failureAnnSegments;
133219
this.successAnnSegments = successAnnSegments;
@@ -137,7 +223,11 @@ public Parameters(String[] initialPromptParam,
137223
this.hotWords = hotWords;
138224
this.waitingTimeForInput = waitingTimeForInput;
139225
this.postSpeechTimer = postSpeechTimer;
226+
this.minimumNumDigits = minimumNumDigits;
227+
this.maximumNumDigits = maximumNumDigits;
228+
this.digitPattern = digitPattern;
140229
this.lang = lang;
230+
this.inputType = inputType;
141231
}
142232

143233

@@ -210,6 +300,46 @@ public String getDriver() {
210300
return driver;
211301
}
212302

303+
/**
304+
* The minimum number of digits to collect.
305+
* <p>
306+
* <b>Defaults to one.</b> This parameter should not be specified if the Digit Pattern parameter is present.
307+
* </p>
308+
*
309+
* @return
310+
*/
311+
public int getMinimumNumDigits() {
312+
return minimumNumDigits;
313+
}
314+
315+
/**
316+
* The maximum number of digits to collect.
317+
* <p>
318+
* <b>Defaults to one.</b> This parameter should not be specified if the Digit Pattern parameter is present.
319+
* </p>
320+
*
321+
* @return
322+
*/
323+
public int getMaximumNumDigits() {
324+
return maximumNumDigits;
325+
}
326+
327+
/**
328+
* A legal digit map as described in <a href="https://tools.ietf.org/html/rfc2885#section-7.1.14">section 7.1.14</a> of the
329+
* MEGACO protocol using the DTMF mappings associated with the Megaco DTMF Detection Package described in the Megaco
330+
* protocol document.
331+
* <p>
332+
* <b>This parameter should not be specified if one or both of the Minimum # Of Digits parameter and the Maximum Number Of
333+
* Digits parameter is present.</b>
334+
* </p>
335+
*
336+
* @return The digit pattern or an empty String if not specified.
337+
*/
338+
public String getDigitPattern() {
339+
return digitPattern;
340+
}
341+
342+
213343
public String getLang() {
214344
return lang;
215345
}
@@ -218,6 +348,10 @@ public List<String> getHotWords() {
218348
return hotWords;
219349
}
220350

351+
public String getInputType() {
352+
return inputType;
353+
}
354+
221355
@Override
222356
public String toString() {
223357
return "Parameters{" +
@@ -230,7 +364,11 @@ public String toString() {
230364
", hotWords='" + hotWords + '\'' +
231365
", waitingTimeForInput=" + waitingTimeForInput +
232366
", postSpeechTimer=" + postSpeechTimer +
367+
", minimumNumDigits=" + minimumNumDigits +
368+
", maximumNumDigits=" + maximumNumDigits +
369+
", digitPattern=" + digitPattern +
233370
", lang='" + lang + '\'' +
371+
", inputType='" + inputType + '\'' +
234372
'}';
235373
}
236374
}

controls/mgcp2/src/main/java/org/mobicents/media/control/mgcp/pkg/au/asr/AsrEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public enum AsrEvent {
3030
WAITING_FOR_RESPONSE_TIMEOUT,
3131
EVALUATE, TIMEOUT, CANCEL,
3232
PLAY_SUCCESS, PLAY_FAILURE, SUCCEED, FAIL,
33-
NO_RECOGNIZED_TEXT, RECOGNIZED_TEXT;
33+
NO_RECOGNIZED_TEXT, PATTERN_MISMATCH, RECOGNIZED_TEXT;
3434

3535
}

controls/mgcp2/src/main/java/org/mobicents/media/control/mgcp/pkg/au/asr/AsrFsmBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ private AsrFsmBuilder() {
8686
this.builder.onEntry(AsrState.EVALUATING).callMethod("enterEvaluating");
8787
this.builder.transition().from(AsrState.EVALUATING).to(AsrState.SUCCEEDING).on(AsrEvent.SUCCEED);
8888
this.builder.transition().from(AsrState.EVALUATING).to(AsrState.FAILING).on(AsrEvent.NO_RECOGNIZED_TEXT);
89+
this.builder.transition().from(AsrState.EVALUATING).to(AsrState.FAILING).on(AsrEvent.PATTERN_MISMATCH);
8990
this.builder.transition(TransitionPriority.HIGHEST).from(AsrState.EVALUATING).to(AsrState.CANCELED).on(AsrEvent.CANCEL);
9091
this.builder.onExit(AsrState.EVALUATING).callMethod("exitEvaluating");
9192

0 commit comments

Comments
 (0)