Mon Jun 27 16:50:58 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 73 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 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

Enumerator:
DMODE_INIT 
DMODE_RECORD 
DMODE_PLAY 

Definition at line 67 of file app_dictate.c.

00067              {
00068    DMODE_INIT,
00069    DMODE_RECORD,
00070    DMODE_PLAY
00071 } dmodes;


Function Documentation

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 }


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 = "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.


Generated on Mon Jun 27 16:50:58 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7