#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, const char *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 | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Virtual Dictation Machine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static const char | app [] = "Dictate" |
static struct ast_module_info * | ast_module_info = &__mod_info |
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) |
enum dflags |
Definition at line 60 of file app_dictate.c.
00060 { 00061 DFLAG_RECORD = (1 << 0), 00062 DFLAG_PLAY = (1 << 1), 00063 DFLAG_TRUNC = (1 << 2), 00064 DFLAG_PAUSE = (1 << 3), 00065 } dflags;
enum dmodes |
Definition at line 67 of file app_dictate.c.
00067 { 00068 DMODE_INIT, 00069 DMODE_RECORD, 00070 DMODE_PLAY 00071 } 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, | |
const char * | data | |||
) | [static] |
Definition at line 84 of file app_dictate.c.
References ast_channel::_state, args, 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::flags, ast_flags::flags, ast_channel::language, len(), LOG_WARNING, parse(), play_and_wait(), ast_channel::readformat, ast_frame::samples, and ast_channel::stream.
Referenced by load_module().
00085 { 00086 char *path = NULL, filein[256], *filename = ""; 00087 char *parse; 00088 AST_DECLARE_APP_ARGS(args, 00089 AST_APP_ARG(base); 00090 AST_APP_ARG(filename); 00091 ); 00092 char dftbase[256]; 00093 char *base; 00094 struct ast_flags flags = {0}; 00095 struct ast_filestream *fs; 00096 struct ast_frame *f = NULL; 00097 int ffactor = 320 * 80, 00098 res = 0, 00099 done = 0, 00100 oldr = 0, 00101 lastop = 0, 00102 samples = 0, 00103 speed = 1, 00104 digit = 0, 00105 len = 0, 00106 maxlen = 0, 00107 mode = 0; 00108 00109 snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR); 00110 if (!ast_strlen_zero(data)) { 00111 parse = ast_strdupa(data); 00112 AST_STANDARD_APP_ARGS(args, parse); 00113 } else 00114 args.argc = 0; 00115 00116 if (args.argc && !ast_strlen_zero(args.base)) { 00117 base = args.base; 00118 } else { 00119 base = dftbase; 00120 } 00121 if (args.argc > 1 && args.filename) { 00122 filename = args.filename; 00123 } 00124 oldr = chan->readformat; 00125 if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) { 00126 ast_log(LOG_WARNING, "Unable to set to linear mode.\n"); 00127 return -1; 00128 } 00129 00130 if (chan->_state != AST_STATE_UP) { 00131 ast_answer(chan); 00132 } 00133 ast_safe_sleep(chan, 200); 00134 for (res = 0; !res;) { 00135 if (ast_strlen_zero(filename)) { 00136 if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) || 00137 ast_strlen_zero(filein)) { 00138 res = -1; 00139 break; 00140 } 00141 } else { 00142 ast_copy_string(filein, filename, sizeof(filein)); 00143 filename = ""; 00144 } 00145 ast_mkdir(base, 0755); 00146 len = strlen(base) + strlen(filein) + 2; 00147 if (!path || len > maxlen) { 00148 path = alloca(len); 00149 memset(path, 0, len); 00150 maxlen = len; 00151 } else { 00152 memset(path, 0, maxlen); 00153 } 00154 00155 snprintf(path, len, "%s/%s", base, filein); 00156 fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE); 00157 mode = DMODE_PLAY; 00158 memset(&flags, 0, sizeof(flags)); 00159 ast_set_flag(&flags, DFLAG_PAUSE); 00160 digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY); 00161 done = 0; 00162 speed = 1; 00163 res = 0; 00164 lastop = 0; 00165 samples = 0; 00166 while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) { 00167 if (digit) { 00168 struct ast_frame fr = {AST_FRAME_DTMF, { .integer = digit } }; 00169 ast_queue_frame(chan, &fr); 00170 digit = 0; 00171 } 00172 if ((f->frametype == AST_FRAME_DTMF)) { 00173 int got = 1; 00174 switch(mode) { 00175 case DMODE_PLAY: 00176 switch (f->subclass.integer) { 00177 case '1': 00178 ast_set_flag(&flags, DFLAG_PAUSE); 00179 mode = DMODE_RECORD; 00180 break; 00181 case '2': 00182 speed++; 00183 if (speed > 4) { 00184 speed = 1; 00185 } 00186 res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, NULL); 00187 break; 00188 case '7': 00189 samples -= ffactor; 00190 if(samples < 0) { 00191 samples = 0; 00192 } 00193 ast_seekstream(fs, samples, SEEK_SET); 00194 break; 00195 case '8': 00196 samples += ffactor; 00197 ast_seekstream(fs, samples, SEEK_SET); 00198 break; 00199 00200 default: 00201 got = 0; 00202 } 00203 break; 00204 case DMODE_RECORD: 00205 switch (f->subclass.integer) { 00206 case '1': 00207 ast_set_flag(&flags, DFLAG_PAUSE); 00208 mode = DMODE_PLAY; 00209 break; 00210 case '8': 00211 ast_toggle_flag(&flags, DFLAG_TRUNC); 00212 lastop = 0; 00213 break; 00214 default: 00215 got = 0; 00216 } 00217 break; 00218 default: 00219 got = 0; 00220 } 00221 if (!got) { 00222 switch (f->subclass.integer) { 00223 case '#': 00224 done = 1; 00225 continue; 00226 break; 00227 case '*': 00228 ast_toggle_flag(&flags, DFLAG_PAUSE); 00229 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00230 digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY); 00231 } else { 00232 digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY); 00233 } 00234 break; 00235 case '0': 00236 ast_set_flag(&flags, DFLAG_PAUSE); 00237 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00238 switch(mode) { 00239 case DMODE_PLAY: 00240 digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY); 00241 break; 00242 case DMODE_RECORD: 00243 digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY); 00244 break; 00245 } 00246 if (digit == 0) { 00247 digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY); 00248 } else if (digit < 0) { 00249 done = 1; 00250 break; 00251 } 00252 break; 00253 } 00254 } 00255 00256 } else if (f->frametype == AST_FRAME_VOICE) { 00257 switch(mode) { 00258 struct ast_frame *fr; 00259 int x; 00260 case DMODE_PLAY: 00261 if (lastop != DMODE_PLAY) { 00262 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00263 digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY); 00264 if (digit == 0) { 00265 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00266 } else if (digit < 0) { 00267 break; 00268 } 00269 } 00270 if (lastop != DFLAG_PLAY) { 00271 lastop = DFLAG_PLAY; 00272 ast_closestream(fs); 00273 if (!(fs = ast_openstream(chan, path, chan->language))) 00274 break; 00275 ast_seekstream(fs, samples, SEEK_SET); 00276 chan->stream = NULL; 00277 } 00278 lastop = DMODE_PLAY; 00279 } 00280 00281 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00282 for (x = 0; x < speed; x++) { 00283 if ((fr = ast_readframe(fs))) { 00284 ast_write(chan, fr); 00285 samples += fr->samples; 00286 ast_frfree(fr); 00287 fr = NULL; 00288 } else { 00289 samples = 0; 00290 ast_seekstream(fs, 0, SEEK_SET); 00291 } 00292 } 00293 } 00294 break; 00295 case DMODE_RECORD: 00296 if (lastop != DMODE_RECORD) { 00297 int oflags = O_CREAT | O_WRONLY; 00298 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00299 digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY); 00300 if (digit == 0) { 00301 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00302 } else if (digit < 0) { 00303 break; 00304 } 00305 } 00306 lastop = DMODE_RECORD; 00307 ast_closestream(fs); 00308 if ( ast_test_flag(&flags, DFLAG_TRUNC)) { 00309 oflags |= O_TRUNC; 00310 digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY); 00311 } else { 00312 oflags |= O_APPEND; 00313 } 00314 fs = ast_writefile(path, "raw", NULL, oflags, 0, AST_FILE_MODE); 00315 if (ast_test_flag(&flags, DFLAG_TRUNC)) { 00316 ast_seekstream(fs, 0, SEEK_SET); 00317 ast_clear_flag(&flags, DFLAG_TRUNC); 00318 } else { 00319 ast_seekstream(fs, 0, SEEK_END); 00320 } 00321 } 00322 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00323 res = ast_writestream(fs, f); 00324 } 00325 break; 00326 } 00327 00328 } 00329 00330 ast_frfree(f); 00331 } 00332 } 00333 if (oldr) { 00334 ast_set_read_format(chan, oldr); 00335 } 00336 return 0; 00337 }
static int load_module | ( | void | ) | [static] |
Definition at line 346 of file app_dictate.c.
References ast_register_application_xml, and dictate_exec().
00347 { 00348 return ast_register_application_xml(app, dictate_exec); 00349 }
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().
00076 { 00077 int res = -1; 00078 if (!ast_streamfile(chan, file, chan->language)) { 00079 res = ast_waitstream(chan, digits); 00080 } 00081 return res; 00082 }
static int unload_module | ( | void | ) | [static] |
Definition at line 339 of file app_dictate.c.
References ast_unregister_application().
00340 { 00341 int res; 00342 res = ast_unregister_application(app); 00343 return res; 00344 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Virtual Dictation Machine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 351 of file app_dictate.c.
const 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.