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