Mon Oct 8 12:39:07 2012

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, 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static const char app [] = "Dictate"
static struct ast_module_infoast_module_info = &__mod_info


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 77 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 64 of file app_dictate.c.

00064              {
00065    DFLAG_RECORD = (1 << 0),
00066    DFLAG_PLAY = (1 << 1),
00067    DFLAG_TRUNC = (1 << 2),
00068    DFLAG_PAUSE = (1 << 3),
00069 } dflags;

enum dmodes

Enumerator:
DMODE_INIT 
DMODE_RECORD 
DMODE_PLAY 

Definition at line 71 of file app_dictate.c.

00071              {
00072    DMODE_INIT,
00073    DMODE_RECORD,
00074    DMODE_PLAY
00075 } dmodes;


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 355 of file app_dictate.c.

static void __unreg_module ( void   )  [static]

Definition at line 355 of file app_dictate.c.

static int dictate_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 88 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().

00089 {
00090    char *path = NULL, filein[256], *filename = "";
00091    char *parse;
00092    AST_DECLARE_APP_ARGS(args,
00093       AST_APP_ARG(base);
00094       AST_APP_ARG(filename);
00095    );
00096    char dftbase[256];
00097    char *base;
00098    struct ast_flags flags = {0};
00099    struct ast_filestream *fs;
00100    struct ast_frame *f = NULL;
00101    int ffactor = 320 * 80,
00102       res = 0,
00103       done = 0,
00104       oldr = 0,
00105       lastop = 0,
00106       samples = 0,
00107       speed = 1,
00108       digit = 0,
00109       len = 0,
00110       maxlen = 0,
00111       mode = 0;
00112 
00113    snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
00114    if (!ast_strlen_zero(data)) {
00115       parse = ast_strdupa(data);
00116       AST_STANDARD_APP_ARGS(args, parse);
00117    } else
00118       args.argc = 0;
00119 
00120    if (args.argc && !ast_strlen_zero(args.base)) {
00121       base = args.base;
00122    } else {
00123       base = dftbase;
00124    }
00125    if (args.argc > 1 && args.filename) {
00126       filename = args.filename;
00127    }
00128    oldr = chan->readformat;
00129    if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
00130       ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
00131       return -1;
00132    }
00133 
00134    if (chan->_state != AST_STATE_UP) {
00135       ast_answer(chan);
00136    }
00137    ast_safe_sleep(chan, 200);
00138    for (res = 0; !res;) {
00139       if (ast_strlen_zero(filename)) {
00140          if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) ||
00141             ast_strlen_zero(filein)) {
00142             res = -1;
00143             break;
00144          }
00145       } else {
00146          ast_copy_string(filein, filename, sizeof(filein));
00147          filename = "";
00148       }
00149       ast_mkdir(base, 0755);
00150       len = strlen(base) + strlen(filein) + 2;
00151       if (!path || len > maxlen) {
00152          path = alloca(len);
00153          memset(path, 0, len);
00154          maxlen = len;
00155       } else {
00156          memset(path, 0, maxlen);
00157       }
00158 
00159       snprintf(path, len, "%s/%s", base, filein);
00160       fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE);
00161       mode = DMODE_PLAY;
00162       memset(&flags, 0, sizeof(flags));
00163       ast_set_flag(&flags, DFLAG_PAUSE);
00164       digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY);
00165       done = 0;
00166       speed = 1;
00167       res = 0;
00168       lastop = 0;
00169       samples = 0;
00170       while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) {
00171          if (digit) {
00172             struct ast_frame fr = {AST_FRAME_DTMF, { .integer = digit } };
00173             ast_queue_frame(chan, &fr);
00174             digit = 0;
00175          }
00176          if ((f->frametype == AST_FRAME_DTMF)) {
00177             int got = 1;
00178             switch(mode) {
00179             case DMODE_PLAY:
00180                switch (f->subclass.integer) {
00181                case '1':
00182                   ast_set_flag(&flags, DFLAG_PAUSE);
00183                   mode = DMODE_RECORD;
00184                   break;
00185                case '2':
00186                   speed++;
00187                   if (speed > 4) {
00188                      speed = 1;
00189                   }
00190                   res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, NULL);
00191                   break;
00192                case '7':
00193                   samples -= ffactor;
00194                   if(samples < 0) {
00195                      samples = 0;
00196                   }
00197                   ast_seekstream(fs, samples, SEEK_SET);
00198                   break;
00199                case '8':
00200                   samples += ffactor;
00201                   ast_seekstream(fs, samples, SEEK_SET);
00202                   break;
00203                   
00204                default:
00205                   got = 0;
00206                }
00207                break;
00208             case DMODE_RECORD:
00209                switch (f->subclass.integer) {
00210                case '1':
00211                   ast_set_flag(&flags, DFLAG_PAUSE);
00212                   mode = DMODE_PLAY;
00213                   break;
00214                case '8':
00215                   ast_toggle_flag(&flags, DFLAG_TRUNC);
00216                   lastop = 0;
00217                   break;
00218                default:
00219                   got = 0;
00220                }
00221                break;
00222             default:
00223                got = 0;
00224             }
00225             if (!got) {
00226                switch (f->subclass.integer) {
00227                case '#':
00228                   done = 1;
00229                   continue;
00230                   break;
00231                case '*':
00232                   ast_toggle_flag(&flags, DFLAG_PAUSE);
00233                   if (ast_test_flag(&flags, DFLAG_PAUSE)) {
00234                      digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY);
00235                   } else {
00236                      digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY);
00237                   }
00238                   break;
00239                case '0':
00240                   ast_set_flag(&flags, DFLAG_PAUSE);
00241                   digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
00242                   switch(mode) {
00243                   case DMODE_PLAY:
00244                      digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY);
00245                      break;
00246                   case DMODE_RECORD:
00247                      digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY);
00248                      break;
00249                   }
00250                   if (digit == 0) {
00251                      digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY);
00252                   } else if (digit < 0) {
00253                      done = 1;
00254                      break;
00255                   }
00256                   break;
00257                }
00258             }
00259             
00260          } else if (f->frametype == AST_FRAME_VOICE) {
00261             switch(mode) {
00262                struct ast_frame *fr;
00263                int x;
00264             case DMODE_PLAY:
00265                if (lastop != DMODE_PLAY) {
00266                   if (ast_test_flag(&flags, DFLAG_PAUSE)) {
00267                      digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY);
00268                      if (digit == 0) {
00269                         digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
00270                      } else if (digit < 0) {
00271                         break;
00272                      }
00273                   }
00274                   if (lastop != DFLAG_PLAY) {
00275                      lastop = DFLAG_PLAY;
00276                      ast_closestream(fs);
00277                      if (!(fs = ast_openstream(chan, path, chan->language)))
00278                         break;
00279                      ast_seekstream(fs, samples, SEEK_SET);
00280                      chan->stream = NULL;
00281                   }
00282                   lastop = DMODE_PLAY;
00283                }
00284 
00285                if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
00286                   for (x = 0; x < speed; x++) {
00287                      if ((fr = ast_readframe(fs))) {
00288                         ast_write(chan, fr);
00289                         samples += fr->samples;
00290                         ast_frfree(fr);
00291                         fr = NULL;
00292                      } else {
00293                         samples = 0;
00294                         ast_seekstream(fs, 0, SEEK_SET);
00295                      }
00296                   }
00297                }
00298                break;
00299             case DMODE_RECORD:
00300                if (lastop != DMODE_RECORD) {
00301                   int oflags = O_CREAT | O_WRONLY;
00302                   if (ast_test_flag(&flags, DFLAG_PAUSE)) {
00303                      digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY);
00304                      if (digit == 0) {
00305                         digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
00306                      } else if (digit < 0) {
00307                         break;
00308                      }
00309                   }
00310                   lastop = DMODE_RECORD;
00311                   ast_closestream(fs);
00312                   if ( ast_test_flag(&flags, DFLAG_TRUNC)) {
00313                      oflags |= O_TRUNC;
00314                      digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY);
00315                   } else {
00316                      oflags |= O_APPEND;
00317                   }
00318                   fs = ast_writefile(path, "raw", NULL, oflags, 0, AST_FILE_MODE);
00319                   if (ast_test_flag(&flags, DFLAG_TRUNC)) {
00320                      ast_seekstream(fs, 0, SEEK_SET);
00321                      ast_clear_flag(&flags, DFLAG_TRUNC);
00322                   } else {
00323                      ast_seekstream(fs, 0, SEEK_END);
00324                   }
00325                }
00326                if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
00327                   res = ast_writestream(fs, f);
00328                }
00329                break;
00330             }
00331             
00332          }
00333 
00334          ast_frfree(f);
00335       }
00336    }
00337    if (oldr) {
00338       ast_set_read_format(chan, oldr);
00339    }
00340    return 0;
00341 }

static int load_module ( void   )  [static]

Definition at line 350 of file app_dictate.c.

References ast_register_application_xml, and dictate_exec().

00351 {
00352    return ast_register_application_xml(app, dictate_exec);
00353 }

static int play_and_wait ( struct ast_channel chan,
char *  file,
char *  digits 
) [static]

Definition at line 79 of file app_dictate.c.

References ast_streamfile(), ast_waitstream(), and ast_channel::language.

Referenced by dictate_exec().

00080 {
00081    int res = -1;
00082    if (!ast_streamfile(chan, file, chan->language)) {
00083       res = ast_waitstream(chan, digits);
00084    }
00085    return res;
00086 }

static int unload_module ( void   )  [static]

Definition at line 343 of file app_dictate.c.

References ast_unregister_application().

00344 {
00345    int res;
00346    res = ast_unregister_application(app);
00347    return res;
00348 }


Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 355 of file app_dictate.c.

const char app[] = "Dictate" [static]

Definition at line 62 of file app_dictate.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 355 of file app_dictate.c.


Generated on Mon Oct 8 12:39:07 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7