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.