#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 | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static char * | app = "Dictate" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | desc |
static char * | synopsis = "Virtual Dictation Machine" |
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 49 of file app_dictate.c.
00049 { 00050 DFLAG_RECORD = (1 << 0), 00051 DFLAG_PLAY = (1 << 1), 00052 DFLAG_TRUNC = (1 << 2), 00053 DFLAG_PAUSE = (1 << 3), 00054 } dflags;
enum dmodes |
Definition at line 56 of file app_dictate.c.
00056 { 00057 DMODE_INIT, 00058 DMODE_RECORD, 00059 DMODE_PLAY 00060 } dmodes;
static void __reg_module | ( | void | ) | [static] |
Definition at line 340 of file app_dictate.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 340 of file app_dictate.c.
static int dictate_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 73 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(), chan, 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().
00074 { 00075 char *path = NULL, filein[256], *filename = ""; 00076 char *parse; 00077 AST_DECLARE_APP_ARGS(args, 00078 AST_APP_ARG(base); 00079 AST_APP_ARG(filename); 00080 ); 00081 char dftbase[256]; 00082 char *base; 00083 struct ast_flags flags = {0}; 00084 struct ast_filestream *fs; 00085 struct ast_frame *f = NULL; 00086 int ffactor = 320 * 80, 00087 res = 0, 00088 done = 0, 00089 oldr = 0, 00090 lastop = 0, 00091 samples = 0, 00092 speed = 1, 00093 digit = 0, 00094 len = 0, 00095 maxlen = 0, 00096 mode = 0; 00097 00098 snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR); 00099 if (!ast_strlen_zero(data)) { 00100 parse = ast_strdupa(data); 00101 AST_STANDARD_APP_ARGS(args, parse); 00102 } else 00103 args.argc = 0; 00104 00105 if (args.argc && !ast_strlen_zero(args.base)) { 00106 base = args.base; 00107 } else { 00108 base = dftbase; 00109 } 00110 if (args.argc > 1 && args.filename) { 00111 filename = args.filename; 00112 } 00113 oldr = chan->readformat; 00114 if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) { 00115 ast_log(LOG_WARNING, "Unable to set to linear mode.\n"); 00116 return -1; 00117 } 00118 00119 if (chan->_state != AST_STATE_UP) { 00120 ast_answer(chan); 00121 } 00122 ast_safe_sleep(chan, 200); 00123 for (res = 0; !res;) { 00124 if (ast_strlen_zero(filename)) { 00125 if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) || 00126 ast_strlen_zero(filein)) { 00127 res = -1; 00128 break; 00129 } 00130 } else { 00131 ast_copy_string(filein, filename, sizeof(filein)); 00132 filename = ""; 00133 } 00134 ast_mkdir(base, 0755); 00135 len = strlen(base) + strlen(filein) + 2; 00136 if (!path || len > maxlen) { 00137 path = alloca(len); 00138 memset(path, 0, len); 00139 maxlen = len; 00140 } else { 00141 memset(path, 0, maxlen); 00142 } 00143 00144 snprintf(path, len, "%s/%s", base, filein); 00145 fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE); 00146 mode = DMODE_PLAY; 00147 memset(&flags, 0, sizeof(flags)); 00148 ast_set_flag(&flags, DFLAG_PAUSE); 00149 digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY); 00150 done = 0; 00151 speed = 1; 00152 res = 0; 00153 lastop = 0; 00154 samples = 0; 00155 while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) { 00156 if (digit) { 00157 struct ast_frame fr = {AST_FRAME_DTMF, digit}; 00158 ast_queue_frame(chan, &fr); 00159 digit = 0; 00160 } 00161 if ((f->frametype == AST_FRAME_DTMF)) { 00162 int got = 1; 00163 switch(mode) { 00164 case DMODE_PLAY: 00165 switch(f->subclass) { 00166 case '1': 00167 ast_set_flag(&flags, DFLAG_PAUSE); 00168 mode = DMODE_RECORD; 00169 break; 00170 case '2': 00171 speed++; 00172 if (speed > 4) { 00173 speed = 1; 00174 } 00175 res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, NULL); 00176 break; 00177 case '7': 00178 samples -= ffactor; 00179 if(samples < 0) { 00180 samples = 0; 00181 } 00182 ast_seekstream(fs, samples, SEEK_SET); 00183 break; 00184 case '8': 00185 samples += ffactor; 00186 ast_seekstream(fs, samples, SEEK_SET); 00187 break; 00188 00189 default: 00190 got = 0; 00191 } 00192 break; 00193 case DMODE_RECORD: 00194 switch(f->subclass) { 00195 case '1': 00196 ast_set_flag(&flags, DFLAG_PAUSE); 00197 mode = DMODE_PLAY; 00198 break; 00199 case '8': 00200 ast_toggle_flag(&flags, DFLAG_TRUNC); 00201 lastop = 0; 00202 break; 00203 default: 00204 got = 0; 00205 } 00206 break; 00207 default: 00208 got = 0; 00209 } 00210 if (!got) { 00211 switch(f->subclass) { 00212 case '#': 00213 done = 1; 00214 continue; 00215 break; 00216 case '*': 00217 ast_toggle_flag(&flags, DFLAG_PAUSE); 00218 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00219 digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY); 00220 } else { 00221 digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY); 00222 } 00223 break; 00224 case '0': 00225 ast_set_flag(&flags, DFLAG_PAUSE); 00226 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00227 switch(mode) { 00228 case DMODE_PLAY: 00229 digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY); 00230 break; 00231 case DMODE_RECORD: 00232 digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY); 00233 break; 00234 } 00235 if (digit == 0) { 00236 digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY); 00237 } else if (digit < 0) { 00238 done = 1; 00239 break; 00240 } 00241 break; 00242 } 00243 } 00244 00245 } else if (f->frametype == AST_FRAME_VOICE) { 00246 switch(mode) { 00247 struct ast_frame *fr; 00248 int x; 00249 case DMODE_PLAY: 00250 if (lastop != DMODE_PLAY) { 00251 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00252 digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY); 00253 if (digit == 0) { 00254 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00255 } else if (digit < 0) { 00256 break; 00257 } 00258 } 00259 if (lastop != DFLAG_PLAY) { 00260 lastop = DFLAG_PLAY; 00261 ast_closestream(fs); 00262 if (!(fs = ast_openstream(chan, path, chan->language))) 00263 break; 00264 ast_seekstream(fs, samples, SEEK_SET); 00265 chan->stream = NULL; 00266 } 00267 lastop = DMODE_PLAY; 00268 } 00269 00270 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00271 for (x = 0; x < speed; x++) { 00272 if ((fr = ast_readframe(fs))) { 00273 ast_write(chan, fr); 00274 samples += fr->samples; 00275 ast_frfree(fr); 00276 fr = NULL; 00277 } else { 00278 samples = 0; 00279 ast_seekstream(fs, 0, SEEK_SET); 00280 } 00281 } 00282 } 00283 break; 00284 case DMODE_RECORD: 00285 if (lastop != DMODE_RECORD) { 00286 int oflags = O_CREAT | O_WRONLY; 00287 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00288 digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY); 00289 if (digit == 0) { 00290 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00291 } else if (digit < 0) { 00292 break; 00293 } 00294 } 00295 lastop = DMODE_RECORD; 00296 ast_closestream(fs); 00297 if ( ast_test_flag(&flags, DFLAG_TRUNC)) { 00298 oflags |= O_TRUNC; 00299 digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY); 00300 } else { 00301 oflags |= O_APPEND; 00302 } 00303 fs = ast_writefile(path, "raw", NULL, oflags, 0, AST_FILE_MODE); 00304 if (ast_test_flag(&flags, DFLAG_TRUNC)) { 00305 ast_seekstream(fs, 0, SEEK_SET); 00306 ast_clear_flag(&flags, DFLAG_TRUNC); 00307 } else { 00308 ast_seekstream(fs, 0, SEEK_END); 00309 } 00310 } 00311 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00312 res = ast_writestream(fs, f); 00313 } 00314 break; 00315 } 00316 00317 } 00318 00319 ast_frfree(f); 00320 } 00321 } 00322 if (oldr) { 00323 ast_set_read_format(chan, oldr); 00324 } 00325 return 0; 00326 }
static int load_module | ( | void | ) | [static] |
Definition at line 335 of file app_dictate.c.
References ast_register_application, and dictate_exec().
00336 { 00337 return ast_register_application(app, dictate_exec, synopsis, desc); 00338 }
static int play_and_wait | ( | struct ast_channel * | chan, | |
char * | file, | |||
char * | digits | |||
) | [static] |
Definition at line 64 of file app_dictate.c.
References ast_streamfile(), ast_waitstream(), chan, and ast_channel::language.
Referenced by dictate_exec().
00065 { 00066 int res = -1; 00067 if (!ast_streamfile(chan, file, chan->language)) { 00068 res = ast_waitstream(chan, digits); 00069 } 00070 return res; 00071 }
static int unload_module | ( | void | ) | [static] |
Definition at line 328 of file app_dictate.c.
References ast_unregister_application().
00329 { 00330 int res; 00331 res = ast_unregister_application(app); 00332 return res; 00333 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 340 of file app_dictate.c.
char* app = "Dictate" [static] |
Definition at line 43 of file app_dictate.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 340 of file app_dictate.c.
char* desc [static] |
Initial value:
" Dictate([<base_dir>[,<filename>]])\n" "Start dictation machine using optional base dir for files.\n"
Definition at line 45 of file app_dictate.c.
char* synopsis = "Virtual Dictation Machine" [static] |
Definition at line 44 of file app_dictate.c.