00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 177385 $");
00031
00032 #include "asterisk/file.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/pbx.h"
00035 #include "asterisk/module.h"
00036 #include "asterisk/lock.h"
00037 #include "asterisk/app.h"
00038 #include "asterisk/speech.h"
00039
00040
00041 static char *speechcreate_descrip =
00042 " SpeechCreate(engine name):\n"
00043 "This application creates information to be used by all the other applications.\n"
00044 "It must be called before doing any speech recognition activities such as activating a grammar.\n"
00045 "It takes the engine name to use as the argument, if not specified the default engine will be used.\n";
00046
00047 static char *speechactivategrammar_descrip =
00048 " SpeechActivateGrammar(Grammar Name):\n"
00049 "This activates the specified grammar to be recognized by the engine.\n"
00050 "A grammar tells the speech recognition engine what to recognize, and how to portray it back to you \n"
00051 "in the dialplan. The grammar name is the only argument to this application.\n";
00052
00053 static char *speechstart_descrip =
00054 " SpeechStart():\n"
00055 "Tell the speech recognition engine that it should start trying to get results from audio being \n"
00056 "fed to it. This has no arguments.\n";
00057
00058 static char *speechbackground_descrip =
00059 " SpeechBackground(<Sound File>[,Timeout[,options]]):\n"
00060 "This application plays a sound file and waits for the person to speak. Once they start speaking playback\n"
00061 "of the file stops, and silence is heard. Once they stop talking the processing sound is played to indicate\n"
00062 "the speech recognition engine is working. Once results are available the application returns and results \n"
00063 "(score and text) are available using dialplan functions.\n"
00064 " The first text and score are ${SPEECH_TEXT(0)} AND ${SPEECH_SCORE(0)} while the second are ${SPEECH_TEXT(1)}\n"
00065 "and ${SPEECH_SCORE(1)}.\n"
00066 " The first argument is the sound file and the second is the timeout integer in seconds. Note the timeout will\n"
00067 "only start once the sound file has stopped playing. The third argument specifies options:\n"
00068 " Valid Options:\n"
00069 " n - Don't answer the channel if it has not already been answered.\n";
00070
00071 static char *speechdeactivategrammar_descrip =
00072 " SpeechDeactivateGrammar(Grammar Name):\n"
00073 "This deactivates the specified grammar so that it is no longer recognized.\n"
00074 "The only argument is the grammar name to deactivate.\n";
00075
00076 static char *speechprocessingsound_descrip =
00077 " SpeechProcessingSound(Sound File):\n"
00078 "This changes the processing sound that SpeechBackground plays back when the speech recognition engine is\n"
00079 "processing and working to get results.\n"
00080 "It takes the sound file as the only argument.\n";
00081
00082 static char *speechdestroy_descrip =
00083 " SpeechDestroy():\n"
00084 "This destroys the information used by all the other speech recognition applications.\n"
00085 "If you call this application but end up wanting to recognize more speech, you must call SpeechCreate\n"
00086 "again before calling any other application. It takes no arguments.\n";
00087
00088 static char *speechload_descrip =
00089 " SpeechLoadGrammar(Grammar Name,Path):\n"
00090 "Load a grammar only on the channel, not globally.\n"
00091 "It takes the grammar name as first argument and path as second.\n";
00092
00093 static char *speechunload_descrip =
00094 " SpeechUnloadGrammar(Grammar Name):\n"
00095 "Unload a grammar. It takes the grammar name as the only argument.\n";
00096
00097
00098 static void destroy_callback(void *data)
00099 {
00100 struct ast_speech *speech = (struct ast_speech*)data;
00101
00102 if (speech == NULL) {
00103 return;
00104 }
00105
00106
00107 ast_speech_destroy(speech);
00108
00109 return;
00110 }
00111
00112
00113 static const struct ast_datastore_info speech_datastore = {
00114 .type = "speech",
00115 .destroy = destroy_callback
00116 };
00117
00118
00119 static struct ast_speech *find_speech(struct ast_channel *chan)
00120 {
00121 struct ast_speech *speech = NULL;
00122 struct ast_datastore *datastore = NULL;
00123
00124 datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
00125 if (datastore == NULL) {
00126 return NULL;
00127 }
00128 speech = datastore->data;
00129
00130 return speech;
00131 }
00132
00133
00134 static struct ast_speech_result *find_result(struct ast_speech_result *results, char *result_num)
00135 {
00136 struct ast_speech_result *result = results;
00137 char *tmp = NULL;
00138 int nbest_num = 0, wanted_num = 0, i = 0;
00139
00140 if (!result)
00141 return NULL;
00142
00143 if ((tmp = strchr(result_num, '/'))) {
00144 *tmp++ = '\0';
00145 nbest_num = atoi(result_num);
00146 wanted_num = atoi(tmp);
00147 } else {
00148 wanted_num = atoi(result_num);
00149 }
00150
00151 do {
00152 if (result->nbest_num != nbest_num)
00153 continue;
00154 if (i == wanted_num)
00155 break;
00156 i++;
00157 } while ((result = AST_LIST_NEXT(result, list)));
00158
00159 return result;
00160 }
00161
00162
00163 static int speech_score(struct ast_channel *chan, const char *cmd, char *data,
00164 char *buf, size_t len)
00165 {
00166 struct ast_speech_result *result = NULL;
00167 struct ast_speech *speech = find_speech(chan);
00168 char tmp[128] = "";
00169
00170 if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
00171 return -1;
00172
00173 snprintf(tmp, sizeof(tmp), "%d", result->score);
00174
00175 ast_copy_string(buf, tmp, len);
00176
00177 return 0;
00178 }
00179
00180 static struct ast_custom_function speech_score_function = {
00181 .name = "SPEECH_SCORE",
00182 .synopsis = "Gets the confidence score of a result.",
00183 .syntax = "SPEECH_SCORE([nbest number/]result number)",
00184 .desc =
00185 "Gets the confidence score of a result.\n",
00186 .read = speech_score,
00187 .write = NULL,
00188 };
00189
00190
00191 static int speech_text(struct ast_channel *chan, const char *cmd, char *data,
00192 char *buf, size_t len)
00193 {
00194 struct ast_speech_result *result = NULL;
00195 struct ast_speech *speech = find_speech(chan);
00196
00197 if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
00198 return -1;
00199
00200 if (result->text != NULL)
00201 ast_copy_string(buf, result->text, len);
00202
00203 return 0;
00204 }
00205
00206 static struct ast_custom_function speech_text_function = {
00207 .name = "SPEECH_TEXT",
00208 .synopsis = "Gets the recognized text of a result.",
00209 .syntax = "SPEECH_TEXT([nbest number/]result number)",
00210 .desc =
00211 "Gets the recognized text of a result.\n",
00212 .read = speech_text,
00213 .write = NULL,
00214 };
00215
00216
00217 static int speech_grammar(struct ast_channel *chan, const char *cmd, char *data,
00218 char *buf, size_t len)
00219 {
00220 struct ast_speech_result *result = NULL;
00221 struct ast_speech *speech = find_speech(chan);
00222
00223 if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
00224 return -1;
00225
00226 if (result->grammar != NULL)
00227 ast_copy_string(buf, result->grammar, len);
00228
00229 return 0;
00230 }
00231
00232 static struct ast_custom_function speech_grammar_function = {
00233 .name = "SPEECH_GRAMMAR",
00234 .synopsis = "Gets the matched grammar of a result if available.",
00235 .syntax = "SPEECH_GRAMMAR([nbest number/]result number)",
00236 .desc =
00237 "Gets the matched grammar of a result if available.\n",
00238 .read = speech_grammar,
00239 .write = NULL,
00240 };
00241
00242
00243 static int speech_engine_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
00244 {
00245 struct ast_speech *speech = find_speech(chan);
00246
00247 if (data == NULL || speech == NULL)
00248 return -1;
00249
00250 ast_speech_change(speech, data, value);
00251
00252 return 0;
00253 }
00254
00255 static struct ast_custom_function speech_engine_function = {
00256 .name = "SPEECH_ENGINE",
00257 .synopsis = "Change a speech engine specific attribute.",
00258 .syntax = "SPEECH_ENGINE(name)=value",
00259 .desc =
00260 "Changes a speech engine specific attribute.\n",
00261 .read = NULL,
00262 .write = speech_engine_write,
00263 };
00264
00265
00266 static int speech_results_type_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
00267 {
00268 struct ast_speech *speech = find_speech(chan);
00269
00270 if (data == NULL || speech == NULL)
00271 return -1;
00272
00273 if (!strcasecmp(value, "normal"))
00274 ast_speech_change_results_type(speech, AST_SPEECH_RESULTS_TYPE_NORMAL);
00275 else if (!strcasecmp(value, "nbest"))
00276 ast_speech_change_results_type(speech, AST_SPEECH_RESULTS_TYPE_NBEST);
00277
00278 return 0;
00279 }
00280
00281 static struct ast_custom_function speech_results_type_function = {
00282 .name = "SPEECH_RESULTS_TYPE",
00283 .synopsis = "Sets the type of results that will be returned.",
00284 .syntax = "SPEECH_RESULTS_TYPE()=results type",
00285 .desc =
00286 "Sets the type of results that will be returned. Valid options are normal or nbest.",
00287 .read = NULL,
00288 .write = speech_results_type_write,
00289 };
00290
00291
00292 static int speech_read(struct ast_channel *chan, const char *cmd, char *data,
00293 char *buf, size_t len)
00294 {
00295 int results = 0;
00296 struct ast_speech_result *result = NULL;
00297 struct ast_speech *speech = find_speech(chan);
00298 char tmp[128] = "";
00299
00300
00301 if (!strcasecmp(data, "status")) {
00302 if (speech != NULL)
00303 ast_copy_string(buf, "1", len);
00304 else
00305 ast_copy_string(buf, "0", len);
00306 return 0;
00307 }
00308
00309
00310 if (speech == NULL) {
00311 return -1;
00312 }
00313
00314
00315 if (!strcasecmp(data, "spoke")) {
00316 if (ast_test_flag(speech, AST_SPEECH_SPOKE))
00317 ast_copy_string(buf, "1", len);
00318 else
00319 ast_copy_string(buf, "0", len);
00320 } else if (!strcasecmp(data, "results")) {
00321
00322 for (result = speech->results; result; result = AST_LIST_NEXT(result, list))
00323 results++;
00324 snprintf(tmp, sizeof(tmp), "%d", results);
00325 ast_copy_string(buf, tmp, len);
00326 }
00327
00328 return 0;
00329 }
00330
00331 static struct ast_custom_function speech_function = {
00332 .name = "SPEECH",
00333 .synopsis = "Gets information about speech recognition results.",
00334 .syntax = "SPEECH(argument)",
00335 .desc =
00336 "Gets information about speech recognition results.\n"
00337 "status: Returns 1 upon speech object existing, or 0 if not\n"
00338 "spoke: Returns 1 if spoker spoke, or 0 if not\n"
00339 "results: Returns number of results that were recognized\n",
00340 .read = speech_read,
00341 .write = NULL,
00342 };
00343
00344
00345
00346
00347 static int speech_create(struct ast_channel *chan, void *data)
00348 {
00349 struct ast_speech *speech = NULL;
00350 struct ast_datastore *datastore = NULL;
00351
00352
00353 speech = ast_speech_new(data, chan->nativeformats);
00354 if (speech == NULL) {
00355
00356 pbx_builtin_setvar_helper(chan, "ERROR", "1");
00357 return 0;
00358 }
00359
00360 datastore = ast_channel_datastore_alloc(&speech_datastore, NULL);
00361 if (datastore == NULL) {
00362 ast_speech_destroy(speech);
00363 pbx_builtin_setvar_helper(chan, "ERROR", "1");
00364 return 0;
00365 }
00366 pbx_builtin_setvar_helper(chan, "ERROR", NULL);
00367 datastore->data = speech;
00368 ast_channel_datastore_add(chan, datastore);
00369
00370 return 0;
00371 }
00372
00373
00374 static int speech_load(struct ast_channel *chan, void *vdata)
00375 {
00376 int res = 0;
00377 struct ast_speech *speech = find_speech(chan);
00378 char *data;
00379 AST_DECLARE_APP_ARGS(args,
00380 AST_APP_ARG(grammar);
00381 AST_APP_ARG(path);
00382 );
00383
00384 data = ast_strdupa(vdata);
00385 AST_STANDARD_APP_ARGS(args, data);
00386
00387 if (speech == NULL)
00388 return -1;
00389
00390 if (args.argc != 2)
00391 return -1;
00392
00393
00394 res = ast_speech_grammar_load(speech, args.grammar, args.path);
00395
00396 return res;
00397 }
00398
00399
00400 static int speech_unload(struct ast_channel *chan, void *data)
00401 {
00402 int res = 0;
00403 struct ast_speech *speech = find_speech(chan);
00404
00405 if (speech == NULL)
00406 return -1;
00407
00408
00409 res = ast_speech_grammar_unload(speech, data);
00410
00411 return res;
00412 }
00413
00414
00415 static int speech_deactivate(struct ast_channel *chan, void *data)
00416 {
00417 int res = 0;
00418 struct ast_speech *speech = find_speech(chan);
00419
00420 if (speech == NULL)
00421 return -1;
00422
00423
00424 res = ast_speech_grammar_deactivate(speech, data);
00425
00426 return res;
00427 }
00428
00429
00430 static int speech_activate(struct ast_channel *chan, void *data)
00431 {
00432 int res = 0;
00433 struct ast_speech *speech = find_speech(chan);
00434
00435 if (speech == NULL)
00436 return -1;
00437
00438
00439 res = ast_speech_grammar_activate(speech, data);
00440
00441 return res;
00442 }
00443
00444
00445 static int speech_start(struct ast_channel *chan, void *data)
00446 {
00447 int res = 0;
00448 struct ast_speech *speech = find_speech(chan);
00449
00450 if (speech == NULL)
00451 return -1;
00452
00453 ast_speech_start(speech);
00454
00455 return res;
00456 }
00457
00458
00459 static int speech_processing_sound(struct ast_channel *chan, void *data)
00460 {
00461 int res = 0;
00462 struct ast_speech *speech = find_speech(chan);
00463
00464 if (speech == NULL)
00465 return -1;
00466
00467 if (speech->processing_sound != NULL) {
00468 ast_free(speech->processing_sound);
00469 speech->processing_sound = NULL;
00470 }
00471
00472 speech->processing_sound = ast_strdup(data);
00473
00474 return res;
00475 }
00476
00477
00478 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
00479 {
00480 struct ast_filestream *fs = NULL;
00481
00482 if (!(fs = ast_openstream(chan, filename, preflang)))
00483 return -1;
00484
00485 if (ast_applystream(chan, fs))
00486 return -1;
00487
00488 ast_playstream(fs);
00489
00490 return 0;
00491 }
00492
00493 enum {
00494 SB_OPT_NOANSWER = (1 << 0),
00495 };
00496
00497 AST_APP_OPTIONS(speech_background_options, BEGIN_OPTIONS
00498 AST_APP_OPTION('n', SB_OPT_NOANSWER),
00499 END_OPTIONS );
00500
00501
00502 static int speech_background(struct ast_channel *chan, void *data)
00503 {
00504 unsigned int timeout = 0;
00505 int res = 0, done = 0, started = 0, quieted = 0, max_dtmf_len = 0;
00506 struct ast_speech *speech = find_speech(chan);
00507 struct ast_frame *f = NULL;
00508 int oldreadformat = AST_FORMAT_SLINEAR;
00509 char dtmf[AST_MAX_EXTENSION] = "";
00510 time_t start, current;
00511 struct ast_datastore *datastore = NULL;
00512 char *parse, *filename_tmp = NULL, *filename = NULL, tmp[2] = "", dtmf_terminator = '#';
00513 const char *tmp2 = NULL;
00514 struct ast_flags options = { 0 };
00515 AST_DECLARE_APP_ARGS(args,
00516 AST_APP_ARG(soundfile);
00517 AST_APP_ARG(timeout);
00518 AST_APP_ARG(options);
00519 );
00520
00521 parse = ast_strdupa(data);
00522 AST_STANDARD_APP_ARGS(args, parse);
00523
00524 if (speech == NULL)
00525 return -1;
00526
00527 if (!ast_strlen_zero(args.options)) {
00528 char *options_buf = ast_strdupa(args.options);
00529 ast_app_parse_options(speech_background_options, &options, NULL, options_buf);
00530 }
00531
00532
00533 if (chan->_state != AST_STATE_UP && !ast_test_flag(&options, SB_OPT_NOANSWER)
00534 && ast_answer(chan)) {
00535 return -1;
00536 }
00537
00538
00539 oldreadformat = chan->readformat;
00540
00541
00542 if (ast_set_read_format(chan, speech->format))
00543 return -1;
00544
00545 if (!ast_strlen_zero(args.soundfile)) {
00546
00547 filename_tmp = ast_strdupa(args.soundfile);
00548 if (!ast_strlen_zero(args.timeout)) {
00549 if ((timeout = atoi(args.timeout)) == 0)
00550 timeout = -1;
00551 } else
00552 timeout = 0;
00553 }
00554
00555
00556 if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_MAXLEN")) && !ast_strlen_zero(tmp2))
00557 max_dtmf_len = atoi(tmp2);
00558
00559
00560 if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_TERMINATOR"))) {
00561 if (ast_strlen_zero(tmp2))
00562 dtmf_terminator = '\0';
00563 else
00564 dtmf_terminator = tmp2[0];
00565 }
00566
00567
00568 if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
00569 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
00570 ast_speech_start(speech);
00571 }
00572
00573
00574 ast_stopstream(chan);
00575
00576
00577 while (done == 0) {
00578
00579 if (!quieted && (chan->streamid == -1 && chan->timingfunc == NULL) && (filename = strsep(&filename_tmp, "&"))) {
00580
00581 ast_stopstream(chan);
00582
00583 speech_streamfile(chan, filename, chan->language);
00584 }
00585
00586
00587 ast_sched_runq(chan->sched);
00588
00589
00590 res = ast_sched_wait(chan->sched);
00591 if (res < 0)
00592 res = 1000;
00593
00594
00595 if (ast_waitfor(chan, res) > 0) {
00596 f = ast_read(chan);
00597 if (f == NULL) {
00598
00599 done = 3;
00600 break;
00601 }
00602 }
00603
00604
00605 if ((!quieted || strlen(dtmf)) && started == 1) {
00606 time(¤t);
00607 if ((current-start) >= timeout) {
00608 done = 1;
00609 if (f)
00610 ast_frfree(f);
00611 break;
00612 }
00613 }
00614
00615
00616 ast_mutex_lock(&speech->lock);
00617 if (ast_test_flag(speech, AST_SPEECH_QUIET)) {
00618 if (chan->stream)
00619 ast_stopstream(chan);
00620 ast_clear_flag(speech, AST_SPEECH_QUIET);
00621 quieted = 1;
00622 }
00623
00624 switch (speech->state) {
00625 case AST_SPEECH_STATE_READY:
00626
00627 if (chan->streamid == -1 && chan->timingfunc == NULL)
00628 ast_stopstream(chan);
00629 if (!quieted && chan->stream == NULL && timeout && started == 0 && !filename_tmp) {
00630 if (timeout == -1) {
00631 done = 1;
00632 if (f)
00633 ast_frfree(f);
00634 break;
00635 }
00636 time(&start);
00637 started = 1;
00638 }
00639
00640 if (!strlen(dtmf) && f != NULL && f->frametype == AST_FRAME_VOICE) {
00641 ast_speech_write(speech, f->data, f->datalen);
00642 }
00643 break;
00644 case AST_SPEECH_STATE_WAIT:
00645
00646 if (!strlen(dtmf)) {
00647 if (chan->stream == NULL) {
00648 if (speech->processing_sound != NULL) {
00649 if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
00650 speech_streamfile(chan, speech->processing_sound, chan->language);
00651 }
00652 }
00653 } else if (chan->streamid == -1 && chan->timingfunc == NULL) {
00654 ast_stopstream(chan);
00655 if (speech->processing_sound != NULL) {
00656 if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
00657 speech_streamfile(chan, speech->processing_sound, chan->language);
00658 }
00659 }
00660 }
00661 }
00662 break;
00663 case AST_SPEECH_STATE_DONE:
00664
00665 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
00666 if (!strlen(dtmf)) {
00667
00668 speech->results = ast_speech_results_get(speech);
00669
00670 done = 1;
00671
00672 if (chan->stream != NULL) {
00673 ast_stopstream(chan);
00674 }
00675 }
00676 break;
00677 default:
00678 break;
00679 }
00680 ast_mutex_unlock(&speech->lock);
00681
00682
00683 if (f != NULL) {
00684
00685 switch (f->frametype) {
00686 case AST_FRAME_DTMF:
00687 if (dtmf_terminator != '\0' && f->subclass == dtmf_terminator) {
00688 done = 1;
00689 } else {
00690 if (chan->stream != NULL) {
00691 ast_stopstream(chan);
00692 }
00693 if (!started) {
00694
00695 timeout = (chan->pbx && chan->pbx->dtimeout) ? chan->pbx->dtimeout : 5;
00696 started = 1;
00697 }
00698 time(&start);
00699 snprintf(tmp, sizeof(tmp), "%c", f->subclass);
00700 strncat(dtmf, tmp, sizeof(dtmf) - strlen(dtmf) - 1);
00701
00702 if (max_dtmf_len && strlen(dtmf) == max_dtmf_len)
00703 done = 1;
00704 }
00705 break;
00706 case AST_FRAME_CONTROL:
00707 switch (f->subclass) {
00708 case AST_CONTROL_HANGUP:
00709
00710 done = 3;
00711 default:
00712 break;
00713 }
00714 default:
00715 break;
00716 }
00717 ast_frfree(f);
00718 f = NULL;
00719 }
00720 }
00721
00722 if (!ast_strlen_zero(dtmf)) {
00723
00724 speech->results = ast_calloc(1, sizeof(*speech->results));
00725 if (speech->results != NULL) {
00726 ast_speech_dtmf(speech, dtmf);
00727 speech->results->score = 1000;
00728 speech->results->text = ast_strdup(dtmf);
00729 speech->results->grammar = ast_strdup("dtmf");
00730 }
00731 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
00732 }
00733
00734
00735 if (done == 3) {
00736
00737 ast_speech_destroy(speech);
00738 datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
00739 if (datastore != NULL)
00740 ast_channel_datastore_remove(chan, datastore);
00741 } else {
00742
00743 ast_set_read_format(chan, oldreadformat);
00744 }
00745
00746 return 0;
00747 }
00748
00749
00750
00751 static int speech_destroy(struct ast_channel *chan, void *data)
00752 {
00753 int res = 0;
00754 struct ast_speech *speech = find_speech(chan);
00755 struct ast_datastore *datastore = NULL;
00756
00757 if (speech == NULL)
00758 return -1;
00759
00760
00761 ast_speech_destroy(speech);
00762
00763 datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
00764 if (datastore != NULL) {
00765 ast_channel_datastore_remove(chan, datastore);
00766 }
00767
00768 return res;
00769 }
00770
00771 static int unload_module(void)
00772 {
00773 int res = 0;
00774
00775 res = ast_unregister_application("SpeechCreate");
00776 res |= ast_unregister_application("SpeechLoadGrammar");
00777 res |= ast_unregister_application("SpeechUnloadGrammar");
00778 res |= ast_unregister_application("SpeechActivateGrammar");
00779 res |= ast_unregister_application("SpeechDeactivateGrammar");
00780 res |= ast_unregister_application("SpeechStart");
00781 res |= ast_unregister_application("SpeechBackground");
00782 res |= ast_unregister_application("SpeechDestroy");
00783 res |= ast_unregister_application("SpeechProcessingSound");
00784 res |= ast_custom_function_unregister(&speech_function);
00785 res |= ast_custom_function_unregister(&speech_score_function);
00786 res |= ast_custom_function_unregister(&speech_text_function);
00787 res |= ast_custom_function_unregister(&speech_grammar_function);
00788 res |= ast_custom_function_unregister(&speech_engine_function);
00789 res |= ast_custom_function_unregister(&speech_results_type_function);
00790
00791 return res;
00792 }
00793
00794 static int load_module(void)
00795 {
00796 int res = 0;
00797
00798 res = ast_register_application("SpeechCreate", speech_create, "Create a Speech Structure", speechcreate_descrip);
00799 res |= ast_register_application("SpeechLoadGrammar", speech_load, "Load a Grammar", speechload_descrip);
00800 res |= ast_register_application("SpeechUnloadGrammar", speech_unload, "Unload a Grammar", speechunload_descrip);
00801 res |= ast_register_application("SpeechActivateGrammar", speech_activate, "Activate a Grammar", speechactivategrammar_descrip);
00802 res |= ast_register_application("SpeechDeactivateGrammar", speech_deactivate, "Deactivate a Grammar", speechdeactivategrammar_descrip);
00803 res |= ast_register_application("SpeechStart", speech_start, "Start recognizing voice in the audio stream", speechstart_descrip);
00804 res |= ast_register_application("SpeechBackground", speech_background, "Play a sound file and wait for speech to be recognized", speechbackground_descrip);
00805 res |= ast_register_application("SpeechDestroy", speech_destroy, "End speech recognition", speechdestroy_descrip);
00806 res |= ast_register_application("SpeechProcessingSound", speech_processing_sound, "Change background processing sound", speechprocessingsound_descrip);
00807 res |= ast_custom_function_register(&speech_function);
00808 res |= ast_custom_function_register(&speech_score_function);
00809 res |= ast_custom_function_register(&speech_text_function);
00810 res |= ast_custom_function_register(&speech_grammar_function);
00811 res |= ast_custom_function_register(&speech_engine_function);
00812 res |= ast_custom_function_register(&speech_results_type_function);
00813
00814 return res;
00815 }
00816
00817 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialplan Speech Applications");