Sat Aug 6 00:39:34 2011

Asterisk developer's documentation


app_dictate.c File Reference

Virtual Dictation Machine Application For Asterisk. More...

#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_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 68 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 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

Enumerator:
DMODE_INIT 
DMODE_RECORD 
DMODE_PLAY 

Definition at line 62 of file app_dictate.c.

00062              {
00063    DMODE_INIT,
00064    DMODE_RECORD,
00065    DMODE_PLAY
00066 } dmodes;


Function Documentation

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 }


Variable Documentation

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.


Generated on Sat Aug 6 00:39:34 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7