61 static const char app[] =
"Dictate";
64 DFLAG_RECORD = (1 << 0),
65 DFLAG_PLAY = (1 << 1),
66 DFLAG_TRUNC = (1 << 2),
67 DFLAG_PAUSE = (1 << 3),
76 #define ast_toggle_flag(it,flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag)
78 static int play_and_wait(
struct ast_channel *chan,
char *file,
char *digits)
87 static int dictate_exec(
struct ast_channel *chan,
const char *data)
89 char *path = NULL, filein[256], *filename =
"";
100 int ffactor = 320 * 80,
112 snprintf(dftbase,
sizeof(dftbase),
"%s/dictate", ast_config_AST_SPOOL_DIR);
113 if (!ast_strlen_zero(data)) {
119 if (args.argc && !ast_strlen_zero(args.base)) {
124 if (args.argc > 1 && args.filename) {
125 filename = args.filename;
127 oldr =
ao2_bump(ast_channel_readformat(chan));
129 ast_log(LOG_WARNING,
"Unable to set to linear mode.\n");
138 for (res = 0; !res;) {
139 if (ast_strlen_zero(filename)) {
140 if (
ast_app_getdata(chan,
"dictate/enter_filename", filein,
sizeof(filein), 0) ||
141 ast_strlen_zero(filein)) {
150 len = strlen(base) + strlen(filein) + 2;
151 if (!path || len > maxlen) {
154 memset(path, 0, len);
157 memset(path, 0, maxlen);
160 snprintf(path, len,
"%s/%s", base, filein);
161 fs =
ast_writefile(path,
"raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE);
163 memset(&flags, 0,
sizeof(flags));
164 ast_set_flag(&flags, DFLAG_PAUSE);
165 digit = play_and_wait(chan,
"dictate/forhelp", AST_DIGIT_ANY);
173 struct ast_frame fr = {AST_FRAME_DTMF, { .integer = digit } };
183 ast_set_flag(&flags, DFLAG_PAUSE);
191 res =
ast_say_number(chan, speed, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
212 ast_set_flag(&flags, DFLAG_PAUSE);
216 ast_toggle_flag(&flags, DFLAG_TRUNC);
233 ast_toggle_flag(&flags, DFLAG_PAUSE);
234 if (ast_test_flag(&flags, DFLAG_PAUSE)) {
235 digit = play_and_wait(chan,
"dictate/pause", AST_DIGIT_ANY);
237 digit = play_and_wait(chan, mode == DMODE_PLAY ?
"dictate/playback" :
"dictate/record", AST_DIGIT_ANY);
241 ast_set_flag(&flags, DFLAG_PAUSE);
242 digit = play_and_wait(chan,
"dictate/paused", AST_DIGIT_ANY);
245 digit = play_and_wait(chan,
"dictate/play_help", AST_DIGIT_ANY);
248 digit = play_and_wait(chan,
"dictate/record_help", AST_DIGIT_ANY);
252 digit = play_and_wait(chan,
"dictate/both_help", AST_DIGIT_ANY);
253 }
else if (digit < 0) {
266 if (lastop != DMODE_PLAY) {
267 if (ast_test_flag(&flags, DFLAG_PAUSE)) {
268 digit = play_and_wait(chan,
"dictate/playback_mode", AST_DIGIT_ANY);
270 digit = play_and_wait(chan,
"dictate/paused", AST_DIGIT_ANY);
271 }
else if (digit < 0) {
275 if (lastop != DFLAG_PLAY) {
278 if (!(fs =
ast_openstream(chan, path, ast_channel_language(chan))))
281 ast_channel_stream_set(chan, NULL);
286 if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
287 for (x = 0; x < speed; x++) {
301 if (lastop != DMODE_RECORD) {
302 int oflags = O_CREAT | O_WRONLY;
303 if (ast_test_flag(&flags, DFLAG_PAUSE)) {
304 digit = play_and_wait(chan,
"dictate/record_mode", AST_DIGIT_ANY);
306 digit = play_and_wait(chan,
"dictate/paused", AST_DIGIT_ANY);
307 }
else if (digit < 0) {
311 lastop = DMODE_RECORD;
313 if ( ast_test_flag(&flags, DFLAG_TRUNC)) {
315 digit = play_and_wait(chan,
"dictate/truncating_audio", AST_DIGIT_ANY);
319 fs =
ast_writefile(path,
"raw", NULL, oflags, 0, AST_FILE_MODE);
320 if (ast_test_flag(&flags, DFLAG_TRUNC)) {
322 ast_clear_flag(&flags, DFLAG_TRUNC);
327 if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
346 static int unload_module(
void)
353 static int load_module(
void)
358 AST_MODULE_INFO_STANDARD_EXTENDED(
ASTERISK_GPL_KEY,
"Virtual Dictation Machine");
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Main Channel structure associated with a channel.
enum ast_getdata_result ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
ast_channel_state
ast_channel states
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int ast_unregister_application(const char *app)
Unregister an application.
struct ast_frame_subclass subclass
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Asterisk file paths, configured in asterisk.conf.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_malloc(len)
A wrapper for malloc()
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
int ast_closestream(struct ast_filestream *f)
Closes a stream.
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Structure used to handle boolean flags.
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
struct ast_filestream * ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang)
Opens stream for use in seeking, playing.
#define AST_APP_ARG(name)
Define an application argument.
int ast_mkdir(const char *path, int mode)
Recursively create directory path.