Fri Aug 17 00:17:21 2018

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

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Virtual Dictation Machine")
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 const char app [] = "Dictate"

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

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Virtual Dictation Machine"   
)
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_alloca, 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::frametype, ast_frame_subclass::integer, len(), LOG_WARNING, parse(), play_and_wait(), ast_channel::readformat, ast_frame::samples, ast_channel::stream, and ast_frame::subclass.

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 = ast_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(), and ast_waitstream().

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

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

Definition at line 62 of file app_dictate.c.


Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1