Virtual Dictation Machine Application For Asterisk. More...
#include "asterisk.h"
#include <sys/stat.h>
#include "asterisk/paths.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
Go to the source code of this file.
Defines | |
#define | ast_toggle_flag(it, flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag) |
Enumerations | |
enum | dflags { DFLAG_RECORD = (1 << 0), DFLAG_PLAY = (1 << 1), DFLAG_TRUNC = (1 << 2), DFLAG_PAUSE = (1 << 3) } |
enum | dmodes { DMODE_INIT, DMODE_RECORD, DMODE_PLAY } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | dictate_exec (struct ast_channel *chan, void *data) |
static int | load_module (void) |
static int | play_and_wait (struct ast_channel *chan, char *file, char *digits) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Virtual Dictation Machine" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
static char * | app = "Dictate" |
static struct ast_module_info * | ast_module_info = &__mod_info |
Virtual Dictation Machine Application For Asterisk.
Definition in file app_dictate.c.
#define ast_toggle_flag | ( | it, | |
flag | |||
) | if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag) |
Definition at line 73 of file app_dictate.c.
Referenced by dictate_exec().
enum dflags |
Definition at line 60 of file app_dictate.c.
{ DFLAG_RECORD = (1 << 0), DFLAG_PLAY = (1 << 1), DFLAG_TRUNC = (1 << 2), DFLAG_PAUSE = (1 << 3), } dflags;
enum dmodes |
Definition at line 67 of file app_dictate.c.
{ DMODE_INIT, DMODE_RECORD, DMODE_PLAY } dmodes;
static void __reg_module | ( | void | ) | [static] |
Definition at line 351 of file app_dictate.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 351 of file app_dictate.c.
static int dictate_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 84 of file app_dictate.c.
References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_clear_flag, ast_closestream(), ast_config_AST_SPOOL_DIR, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, AST_FILE_MODE, AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_mkdir(), ast_openstream(), ast_queue_frame(), ast_read(), ast_readframe(), ast_safe_sleep(), ast_say_number(), ast_seekstream(), ast_set_flag, ast_set_read_format(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_toggle_flag, ast_waitfor(), ast_write(), ast_writefile(), ast_writestream(), DFLAG_PAUSE, DFLAG_PLAY, DFLAG_TRUNC, DMODE_PLAY, DMODE_RECORD, f, ast_frame::frametype, ast_channel::language, len(), LOG_WARNING, parse(), play_and_wait(), ast_channel::readformat, ast_frame::samples, ast_channel::stream, and ast_frame::subclass.
Referenced by load_module().
{ char *path = NULL, filein[256], *filename = ""; char *parse; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(base); AST_APP_ARG(filename); ); char dftbase[256]; char *base; struct ast_flags flags = {0}; struct ast_filestream *fs; struct ast_frame *f = NULL; int ffactor = 320 * 80, res = 0, done = 0, oldr = 0, lastop = 0, samples = 0, speed = 1, digit = 0, len = 0, maxlen = 0, mode = 0; snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR); if (!ast_strlen_zero(data)) { parse = ast_strdupa(data); AST_STANDARD_APP_ARGS(args, parse); } else args.argc = 0; if (args.argc && !ast_strlen_zero(args.base)) { base = args.base; } else { base = dftbase; } if (args.argc > 1 && args.filename) { filename = args.filename; } oldr = chan->readformat; if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) { ast_log(LOG_WARNING, "Unable to set to linear mode.\n"); return -1; } if (chan->_state != AST_STATE_UP) { ast_answer(chan); } ast_safe_sleep(chan, 200); for (res = 0; !res;) { if (ast_strlen_zero(filename)) { if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) || ast_strlen_zero(filein)) { res = -1; break; } } else { ast_copy_string(filein, filename, sizeof(filein)); filename = ""; } ast_mkdir(base, 0755); len = strlen(base) + strlen(filein) + 2; if (!path || len > maxlen) { path = alloca(len); memset(path, 0, len); maxlen = len; } else { memset(path, 0, maxlen); } snprintf(path, len, "%s/%s", base, filein); fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE); mode = DMODE_PLAY; memset(&flags, 0, sizeof(flags)); ast_set_flag(&flags, DFLAG_PAUSE); digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY); done = 0; speed = 1; res = 0; lastop = 0; samples = 0; while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) { if (digit) { struct ast_frame fr = {AST_FRAME_DTMF, digit}; ast_queue_frame(chan, &fr); digit = 0; } if ((f->frametype == AST_FRAME_DTMF)) { int got = 1; switch(mode) { case DMODE_PLAY: switch(f->subclass) { case '1': ast_set_flag(&flags, DFLAG_PAUSE); mode = DMODE_RECORD; break; case '2': speed++; if (speed > 4) { speed = 1; } res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, NULL); break; case '7': samples -= ffactor; if(samples < 0) { samples = 0; } ast_seekstream(fs, samples, SEEK_SET); break; case '8': samples += ffactor; ast_seekstream(fs, samples, SEEK_SET); break; default: got = 0; } break; case DMODE_RECORD: switch(f->subclass) { case '1': ast_set_flag(&flags, DFLAG_PAUSE); mode = DMODE_PLAY; break; case '8': ast_toggle_flag(&flags, DFLAG_TRUNC); lastop = 0; break; default: got = 0; } break; default: got = 0; } if (!got) { switch(f->subclass) { case '#': done = 1; continue; break; case '*': ast_toggle_flag(&flags, DFLAG_PAUSE); if (ast_test_flag(&flags, DFLAG_PAUSE)) { digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY); } else { digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY); } break; case '0': ast_set_flag(&flags, DFLAG_PAUSE); digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); switch(mode) { case DMODE_PLAY: digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY); break; case DMODE_RECORD: digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY); break; } if (digit == 0) { digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY); } else if (digit < 0) { done = 1; break; } break; } } } else if (f->frametype == AST_FRAME_VOICE) { switch(mode) { struct ast_frame *fr; int x; case DMODE_PLAY: if (lastop != DMODE_PLAY) { if (ast_test_flag(&flags, DFLAG_PAUSE)) { digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY); if (digit == 0) { digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); } else if (digit < 0) { break; } } if (lastop != DFLAG_PLAY) { lastop = DFLAG_PLAY; ast_closestream(fs); if (!(fs = ast_openstream(chan, path, chan->language))) break; ast_seekstream(fs, samples, SEEK_SET); chan->stream = NULL; } lastop = DMODE_PLAY; } if (!ast_test_flag(&flags, DFLAG_PAUSE)) { for (x = 0; x < speed; x++) { if ((fr = ast_readframe(fs))) { ast_write(chan, fr); samples += fr->samples; ast_frfree(fr); fr = NULL; } else { samples = 0; ast_seekstream(fs, 0, SEEK_SET); } } } break; case DMODE_RECORD: if (lastop != DMODE_RECORD) { int oflags = O_CREAT | O_WRONLY; if (ast_test_flag(&flags, DFLAG_PAUSE)) { digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY); if (digit == 0) { digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); } else if (digit < 0) { break; } } lastop = DMODE_RECORD; ast_closestream(fs); if ( ast_test_flag(&flags, DFLAG_TRUNC)) { oflags |= O_TRUNC; digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY); } else { oflags |= O_APPEND; } fs = ast_writefile(path, "raw", NULL, oflags, 0, AST_FILE_MODE); if (ast_test_flag(&flags, DFLAG_TRUNC)) { ast_seekstream(fs, 0, SEEK_SET); ast_clear_flag(&flags, DFLAG_TRUNC); } else { ast_seekstream(fs, 0, SEEK_END); } } if (!ast_test_flag(&flags, DFLAG_PAUSE)) { res = ast_writestream(fs, f); } break; } } ast_frfree(f); } } if (oldr) { ast_set_read_format(chan, oldr); } return 0; }
static int load_module | ( | void | ) | [static] |
Definition at line 346 of file app_dictate.c.
References ast_register_application_xml, and dictate_exec().
{ return ast_register_application_xml(app, dictate_exec); }
static int play_and_wait | ( | struct ast_channel * | chan, |
char * | file, | ||
char * | digits | ||
) | [static] |
Definition at line 75 of file app_dictate.c.
References ast_streamfile(), ast_waitstream(), and ast_channel::language.
Referenced by dictate_exec().
{ int res = -1; if (!ast_streamfile(chan, file, chan->language)) { res = ast_waitstream(chan, digits); } return res; }
static int unload_module | ( | void | ) | [static] |
Definition at line 339 of file app_dictate.c.
References ast_unregister_application().
{ int res; res = ast_unregister_application(app); return res; }
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Virtual Dictation Machine" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 351 of file app_dictate.c.
char* app = "Dictate" [static] |
Definition at line 58 of file app_dictate.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 351 of file app_dictate.c.