aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-05-04 19:33:33 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-05-04 19:33:33 +0000
commit3aea9a1dc72c50caece12b2a299f3a9a0dd6c639 (patch)
treeeb8ab6fb7eeeaf7e9dfbc23e581a9a4d41ba16c4
parentcb019df918733bf9c839ca6fac8042f85941908f (diff)
add app_dictate (bug #3893)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5579 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xMakefile11
-rwxr-xr-xapps/Makefile3
-rwxr-xr-xapps/app_dictate.c335
-rwxr-xr-xsounds.txt28
-rwxr-xr-xsounds/dictate/both_help.gsmbin0 -> 8415 bytes
-rwxr-xr-xsounds/dictate/enter_filename.gsmbin0 -> 9339 bytes
-rwxr-xr-xsounds/dictate/forhelp.gsmbin0 -> 2475 bytes
-rwxr-xr-xsounds/dictate/pause.gsmbin0 -> 1122 bytes
-rwxr-xr-xsounds/dictate/paused.gsmbin0 -> 1287 bytes
-rwxr-xr-xsounds/dictate/play_help.gsmbin0 -> 14388 bytes
-rwxr-xr-xsounds/dictate/playback.gsmbin0 -> 1386 bytes
-rwxr-xr-xsounds/dictate/playback_mode.gsmbin0 -> 1848 bytes
-rwxr-xr-xsounds/dictate/record.gsmbin0 -> 1386 bytes
-rwxr-xr-xsounds/dictate/record_help.gsmbin0 -> 8646 bytes
-rwxr-xr-xsounds/dictate/record_mode.gsmbin0 -> 1650 bytes
-rwxr-xr-xsounds/dictate/truncating_audio.gsmbin0 -> 2508 bytes
16 files changed, 375 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 56a50679c..2d305596b 100755
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,6 @@
# Create OPTIONS variable
OPTIONS=
-
# If cross compiling, define these to suit
# CROSS_COMPILE=/opt/montavista/pro/devkit/arm/xscale_be/bin/xscale_be-
# CROSS_COMPILE_BIN=/opt/montavista/pro/devkit/arm/xscale_be/bin/
@@ -411,6 +410,15 @@ datafiles: all
exit 1; \
fi; \
done
+ mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/dictate
+ for x in sounds/dictate/*.gsm; do \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
+ install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/dictate ; \
+ else \
+ echo "No description for $$x"; \
+ exit 1; \
+ fi; \
+ done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters
for x in sounds/letters/*.gsm; do \
if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
@@ -490,6 +498,7 @@ bininstall: all
mkdir -p $(DESTDIR)$(ASTSBINDIR)
mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
+ mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/dictate
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/system
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/tmp
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/meetme
diff --git a/apps/Makefile b/apps/Makefile
index 5d8691088..e1eb61fb9 100755
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -31,7 +31,8 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\
app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \
app_test.so app_forkcdr.so app_math.so app_realtime.so \
app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
- app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so
+ app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so \
+ app_dictate.so
ifneq (${OSARCH},Darwin)
ifneq (${OSARCH},SunOS)
diff --git a/apps/app_dictate.c b/apps/app_dictate.c
new file mode 100755
index 000000000..b88fbf2c3
--- /dev/null
+++ b/apps/app_dictate.c
@@ -0,0 +1,335 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Virtual Dictation Machine Application For Asterisk
+ *
+ * Copyright (C) 2005, Anthony Minessale II
+ *
+ * Anthony Minessale II <anthmct@yahoo.com>
+ *
+ * Donated by Sangoma Technologies <http://www.samgoma.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.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"
+#include "astconf.h"
+
+static char *tdesc = "Virtual Dictation Machine";
+static char *app = "Dictate";
+static char *synopsis = "Virtual Dictation Machine";
+static char *desc = " Dictate([<base_dir>])\n"
+"Start dictation machine using optional base dir for files.\n";
+
+
+STANDARD_LOCAL_USER;
+LOCAL_USER_DECL;
+
+typedef enum {
+ DFLAG_RECORD = (1 << 0),
+ DFLAG_PLAY = (1 << 1),
+ DFLAG_TRUNC = (1 << 2),
+ DFLAG_PAUSE = (1 << 3),
+} dflags;
+
+typedef enum {
+ DMODE_INIT,
+ DMODE_RECORD,
+ DMODE_PLAY
+} dmodes;
+
+#define ast_toggle_flag(it,flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag)
+
+static int play_and_wait(struct ast_channel *chan, char *file, char *digits)
+{
+ int res = -1;
+ if (!ast_streamfile(chan, file, chan->language)) {
+ res = ast_waitstream(chan, digits);
+ }
+ return res;
+}
+
+static int dictate_exec(struct ast_channel *chan, void *data)
+{
+ char *mydata, *argv[2], *path = NULL, filein[256];
+ char dftbase[256];
+ char *base;
+ struct ast_flags flags = {0};
+ struct ast_filestream *fs;
+ struct ast_frame *f = NULL;
+ struct localuser *u;
+ int ffactor = 320 * 80,
+ res = 0,
+ argc = 0,
+ done = 0,
+ oldr = 0,
+ lastop = 0,
+ samples = 0,
+ speed = 1,
+ digit = 0,
+ len = 0,
+ maxlen = 0,
+ mode = 0;
+
+
+ snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
+ if (data && !ast_strlen_zero(data) && (mydata = ast_strdupa(data))) {
+ argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ }
+
+ if (argc) {
+ base = argv[0];
+ } else {
+ base = dftbase;
+ }
+
+ oldr = chan->readformat;
+ if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
+ ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
+ return -1;
+ }
+
+ LOCAL_USER_ADD(u);
+ ast_answer(chan);
+ ast_safe_sleep(chan, 200);
+ for(res = 0; !res;) {
+ if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) ||
+ ast_strlen_zero(filein)) {
+ res = -1;
+ break;
+ }
+
+ mkdir(base, 0755);
+ len = strlen(base) + strlen(filein) + 2;
+ if (!path || len > maxlen) {
+ path = alloca(len);
+ memset(path, 0, len);
+ maxlen = len;
+ } else {
+ memset(path, 0, maxlen);
+ }
+
+ snprintf(path, len, "%s/%s", base, filein);
+ fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, 0700);
+ mode = DMODE_PLAY;
+ memset(&flags, 0, sizeof(flags));
+ ast_set_flag(&flags, DFLAG_PAUSE);
+ digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY);
+ done = 0;
+ speed = 1;
+ res = 0;
+ lastop = 0;
+ samples = 0;
+ while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) {
+ if (digit) {
+ struct ast_frame fr = {AST_FRAME_DTMF, digit};
+ ast_queue_frame(chan, &fr);
+ digit = 0;
+ }
+ if ((f->frametype == AST_FRAME_DTMF)) {
+ int got = 1;
+ switch(mode) {
+ case DMODE_PLAY:
+ switch(f->subclass) {
+ case '1':
+ ast_set_flag(&flags, DFLAG_PAUSE);
+ mode = DMODE_RECORD;
+ break;
+ case '2':
+ speed++;
+ if (speed > 4) {
+ speed = 1;
+ }
+ res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, (char *) NULL);
+ break;
+ case '7':
+ samples -= ffactor;
+ if(samples < 0) {
+ samples = 0;
+ }
+ ast_seekstream(fs, samples, SEEK_SET);
+ break;
+ case '8':
+ samples += ffactor;
+ ast_seekstream(fs, samples, SEEK_SET);
+ break;
+
+ default:
+ got = 0;
+ }
+ break;
+ case DMODE_RECORD:
+ switch(f->subclass) {
+ case '1':
+ ast_set_flag(&flags, DFLAG_PAUSE);
+ mode = DMODE_PLAY;
+ break;
+ case '8':
+ ast_toggle_flag(&flags, DFLAG_TRUNC);
+ lastop = 0;
+ break;
+ default:
+ got = 0;
+ }
+ break;
+ default:
+ got = 0;
+ }
+ if (!got) {
+ switch(f->subclass) {
+ case '#':
+ done = 1;
+ continue;
+ break;
+ case '*':
+ ast_toggle_flag(&flags, DFLAG_PAUSE);
+ if (ast_test_flag(&flags, DFLAG_PAUSE)) {
+ digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY);
+ } else {
+ digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY);
+ }
+ break;
+ case '0':
+ ast_set_flag(&flags, DFLAG_PAUSE);
+ digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
+ switch(mode) {
+ case DMODE_PLAY:
+ digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY);
+ break;
+ case DMODE_RECORD:
+ digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY);
+ break;
+ }
+ if (digit == 0) {
+ digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY);
+ } else if (digit < 0) {
+ done = 1;
+ break;
+ }
+ break;
+ }
+ }
+
+ } else if (f->frametype == AST_FRAME_VOICE) {
+ switch(mode) {
+ struct ast_frame *fr;
+ int x;
+ case DMODE_PLAY:
+ if (lastop != DMODE_PLAY) {
+ if (ast_test_flag(&flags, DFLAG_PAUSE)) {
+ digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY);
+ if (digit == 0) {
+ digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
+ } else if (digit < 0) {
+ break;
+ }
+ }
+ if (lastop != DFLAG_PLAY) {
+ lastop = DFLAG_PLAY;
+ ast_closestream(fs);
+ fs = ast_openstream(chan, path, chan->language);
+ ast_seekstream(fs, samples, SEEK_SET);
+ chan->stream = NULL;
+ }
+ lastop = DMODE_PLAY;
+ }
+
+ if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
+ for (x = 0; x < speed; x++) {
+ if ((fr = ast_readframe(fs))) {
+ ast_write(chan, fr);
+ samples += fr->samples;
+ ast_frfree(fr);
+ fr = NULL;
+ } else {
+ samples = 0;
+ ast_seekstream(fs, 0, SEEK_SET);
+ }
+ }
+ }
+ break;
+ case DMODE_RECORD:
+ if (lastop != DMODE_RECORD) {
+ int oflags = O_CREAT | O_WRONLY;
+ if (ast_test_flag(&flags, DFLAG_PAUSE)) {
+ digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY);
+ if (digit == 0) {
+ digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
+ } else if (digit < 0) {
+ break;
+ }
+ }
+ lastop = DMODE_RECORD;
+ ast_closestream(fs);
+ if ( ast_test_flag(&flags, DFLAG_TRUNC)) {
+ oflags |= O_TRUNC;
+ digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY);
+ } else {
+ oflags |= O_APPEND;
+ }
+ fs = ast_writefile(path, "raw", NULL, oflags, 0, 0700);
+ if (ast_test_flag(&flags, DFLAG_TRUNC)) {
+ ast_seekstream(fs, 0, SEEK_SET);
+ ast_clear_flag(&flags, DFLAG_TRUNC);
+ } else {
+ ast_seekstream(fs, 0, SEEK_END);
+ }
+ }
+ if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
+ res = ast_writestream(fs, f);
+ }
+ break;
+ }
+
+ }
+
+ ast_frfree(f);
+ }
+ }
+ if (oldr) {
+ ast_set_read_format(chan, oldr);
+ }
+ LOCAL_USER_REMOVE(u);
+ return res;
+}
+
+int unload_module(void)
+{
+ STANDARD_HANGUP_LOCALUSERS;
+ return ast_unregister_application(app);
+}
+
+int load_module(void)
+{
+ return ast_register_application(app, dictate_exec, synopsis, desc);
+}
+
+char *description(void)
+{
+ return tdesc;
+}
+
+int usecount(void)
+{
+ int res;
+ STANDARD_USECOUNT(res);
+ return res;
+}
+
+char *key()
+{
+ return ASTERISK_GPL_KEY;
+}
+
diff --git a/sounds.txt b/sounds.txt
index dd8946b67..4250ce5ee 100755
--- a/sounds.txt
+++ b/sounds.txt
@@ -268,6 +268,34 @@
%tt-weasels.gsm%Weasels have eaten our phone system
+;dictate directory - app_dictate
+
+%both_help.gsm%press * to toggle pause, press # to enter a new dictation filename
+
+%enter_filename.gsm%Enter a numeric dictation filename followed by # or just # to exit
+
+%forhelp.gsm%press 0 for help
+
+%inithelp.gsm%1 to switch to playback mode
+
+%pause.gsm%pause
+
+%paused.gsm%paused
+
+%play_help.gsm%press 1 to switch to record mode, press 2 to toggle fast playback, press 7 to jump backwards, press 8 to jump forwards
+
+%playback.gsm%playback
+
+%playback_mode.gsm%playback mode
+
+%record.gsm%record
+
+%record_help.gsm%press 1 to switch to playback mode, press 8 to truncate the file and start over
+
+%record_mode.gsm%record mode
+
+%truncating_audio.gsm%truncating audio
+
;digits directory - File Name Sound File Script
%minus.gsm%minus
diff --git a/sounds/dictate/both_help.gsm b/sounds/dictate/both_help.gsm
new file mode 100755
index 000000000..6416c5855
--- /dev/null
+++ b/sounds/dictate/both_help.gsm
Binary files differ
diff --git a/sounds/dictate/enter_filename.gsm b/sounds/dictate/enter_filename.gsm
new file mode 100755
index 000000000..9de823758
--- /dev/null
+++ b/sounds/dictate/enter_filename.gsm
Binary files differ
diff --git a/sounds/dictate/forhelp.gsm b/sounds/dictate/forhelp.gsm
new file mode 100755
index 000000000..3824a3308
--- /dev/null
+++ b/sounds/dictate/forhelp.gsm
Binary files differ
diff --git a/sounds/dictate/pause.gsm b/sounds/dictate/pause.gsm
new file mode 100755
index 000000000..55fb96f85
--- /dev/null
+++ b/sounds/dictate/pause.gsm
Binary files differ
diff --git a/sounds/dictate/paused.gsm b/sounds/dictate/paused.gsm
new file mode 100755
index 000000000..b48f394b1
--- /dev/null
+++ b/sounds/dictate/paused.gsm
Binary files differ
diff --git a/sounds/dictate/play_help.gsm b/sounds/dictate/play_help.gsm
new file mode 100755
index 000000000..5f854ac98
--- /dev/null
+++ b/sounds/dictate/play_help.gsm
Binary files differ
diff --git a/sounds/dictate/playback.gsm b/sounds/dictate/playback.gsm
new file mode 100755
index 000000000..48c16c186
--- /dev/null
+++ b/sounds/dictate/playback.gsm
Binary files differ
diff --git a/sounds/dictate/playback_mode.gsm b/sounds/dictate/playback_mode.gsm
new file mode 100755
index 000000000..98fd711fc
--- /dev/null
+++ b/sounds/dictate/playback_mode.gsm
Binary files differ
diff --git a/sounds/dictate/record.gsm b/sounds/dictate/record.gsm
new file mode 100755
index 000000000..fe3cee8c6
--- /dev/null
+++ b/sounds/dictate/record.gsm
Binary files differ
diff --git a/sounds/dictate/record_help.gsm b/sounds/dictate/record_help.gsm
new file mode 100755
index 000000000..daf49ba5c
--- /dev/null
+++ b/sounds/dictate/record_help.gsm
Binary files differ
diff --git a/sounds/dictate/record_mode.gsm b/sounds/dictate/record_mode.gsm
new file mode 100755
index 000000000..52203a951
--- /dev/null
+++ b/sounds/dictate/record_mode.gsm
Binary files differ
diff --git a/sounds/dictate/truncating_audio.gsm b/sounds/dictate/truncating_audio.gsm
new file mode 100755
index 000000000..90db78679
--- /dev/null
+++ b/sounds/dictate/truncating_audio.gsm
Binary files differ