Thu Jul 9 13:40:44 2009

Asterisk developer's documentation


app_dictate.c File Reference

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 __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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static char * app = "Dictate"
static const struct ast_module_infoast_module_info = &__mod_info
static char * desc
static char * synopsis = "Virtual Dictation Machine"


Detailed Description

Virtual Dictation Machine Application For Asterisk.

Author:
Anthony Minessale II <anthmct@yahoo.com>

Definition in file app_dictate.c.


Define Documentation

#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 62 of file app_dictate.c.

Referenced by dictate_exec().


Enumeration Type Documentation

enum dflags

Enumerator:
DFLAG_RECORD 
DFLAG_PLAY 
DFLAG_TRUNC 
DFLAG_PAUSE 

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

Enumerator:
DMODE_INIT 
DMODE_RECORD 
DMODE_PLAY 

Definition at line 56 of file app_dictate.c.

00056              {
00057    DMODE_INIT,
00058    DMODE_RECORD,
00059    DMODE_PLAY
00060 } dmodes;


Function Documentation

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 }


Variable Documentation

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 = "068e67f60f50dd9ee86464c05884a49d" , .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.

const 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.


Generated on Thu Jul 9 13:40:44 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7