speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Update protocols to support tone generation.


From: Christopher Brannon
Subject: [PATCH] Update protocols to support tone generation.
Date: Thu, 21 Oct 2010 10:12:59 -0500

This patch updates both the SSIP protocol and the server -> module
protocol with support for tone generation.
A tone is just a beep at a given frequency, played for a given
duration.  E.G., 440 Hz for 2000 milliseconds.
Tones can serve much the same purpose as sound icons.  They provide
a non-verbal auditory indication that some event has occurred.
---
 doc/ssip.texi              |   17 +++++++++++++++
 include/speechd_types.h    |    1 +
 src/modules/module_main.c  |    1 +
 src/modules/module_utils.c |   16 ++++++++++++++
 src/modules/module_utils.h |    1 +
 src/server/msg.h           |    6 +++++
 src/server/output.c        |    1 +
 src/server/parse.c         |   49 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/doc/ssip.texi b/doc/ssip.texi
index 721c2fe..68d70f6 100644
--- a/doc/ssip.texi
+++ b/doc/ssip.texi
@@ -485,6 +485,23 @@ Send a sound identified by @var{icon-name} to the audio 
output.
 @var{icon-name} is a symbolic name of the given sound from the
 standard set listed in @ref{Standard Sound Icons}, or another name
 from the particular Speech Server sound icon configuration.
+
+ at item TONE @var{frequency} @var{duration}
+ at anchor{SSIP TONE}
+Play a tone for @var{duration} milliseconds, at @var{frequency} hertz on the
+audio output.
+ at var{frequency} must be a whole number in the range 50 to 5000 inclusive,
+and @var{duration} must be a whole number in the range 50 to 10000 inclusive.
+
+ at example
+TONE 440 500
+ at end example
+
+The previous example will play a 440 hertz tone for 500 milliseconds.
+
+Tones serve a purpose similar to that of sound icons.
+They indicate occurrences of events using sound, rather than the spoken word.
+
 @end table
 
 @node Speech Output Control Commands, Message Priority Commands, Speech 
Synthesis and Sound Output Commands, SSIP Commands
diff --git a/include/speechd_types.h b/include/speechd_types.h
index 2f3a32d..94f8d3e 100644
--- a/include/speechd_types.h
+++ b/include/speechd_types.h
@@ -48,6 +48,7 @@ typedef enum
        MSGTYPE_SOUND_ICON = 1,
        MSGTYPE_CHAR = 2,
        MSGTYPE_KEY = 3,
+       MSGTYPE_TONE = 4,
        MSGTYPE_SPELL = 99
     }EMessageType;
 
diff --git a/src/modules/module_main.c b/src/modules/module_main.c
index 7bc7774..718bf10 100644
--- a/src/modules/module_main.c
+++ b/src/modules/module_main.c
@@ -166,6 +166,7 @@ main(int argc, char *argv[])
         else PROCESS_CMD(SOUND_ICON, do_sound_icon)
         else PROCESS_CMD(CHAR, do_char)
         else PROCESS_CMD(KEY, do_key)
+        else PROCESS_CMD(TONE, do_tone)
         else PROCESS_CMD_NRP(STOP, do_stop) 
         else PROCESS_CMD_NRP(PAUSE, do_pause) 
         else PROCESS_CMD(LIST VOICES, do_list_voices)
diff --git a/src/modules/module_utils.c b/src/modules/module_utils.c
index 76b308c..e4da445 100644
--- a/src/modules/module_utils.c
+++ b/src/modules/module_utils.c
@@ -84,6 +84,17 @@ do_message(EMessageType msgtype)
        return g_strdup("301 ERROR CANT SPEAK");
     }
 
+    if (msgtype == MSGTYPE_TONE) {
+       /*
+        * Tone-handling code is not yet written.
+        * This block is just a stub, and it will go away as soon as
+        * the module_speak function has a case for MSGTYPE_TONE in all
+        * modules.
+        */
+       g_string_free(msg, TRUE);
+       return g_strdup("200 OK SPEAKING");
+    }
+
     ret = module_speak(msg->str, strlen(msg->str), msgtype);
 
     g_string_free(msg,1);
@@ -116,6 +127,11 @@ do_key(void)
     return do_message(MSGTYPE_KEY);
 }
 
+char*
+do_tone(void)
+{
+    return do_message(MSGTYPE_TONE);
+}
 void
 do_stop(void)
 {
diff --git a/src/modules/module_utils.h b/src/modules/module_utils.h
index def27e5..f8a8031 100644
--- a/src/modules/module_utils.h
+++ b/src/modules/module_utils.h
@@ -209,6 +209,7 @@ char* do_speak(void);
 char* do_sound_icon(void);
 char* do_char(void);
 char* do_key(void);
+char* do_tone(void);
 void  do_stop(void);
 void  do_pause(void);
 char* do_list_voices(void);
diff --git a/src/server/msg.h b/src/server/msg.h
index 36c8fc6..7f6ea4a 100644
--- a/src/server/msg.h
+++ b/src/server/msg.h
@@ -53,6 +53,7 @@
 #define OK_MESSAGE_QUEUED                      "225 OK MESSAGE QUEUED\r\n"
 #define OK_SND_ICON_QUEUED                     "226 OK SOUND ICON QUEUED\r\n"
 #define OK_MSG_CANCELED                                "227 OK MESSAGE 
CANCELED\r\n"
+#define OK_TONE_QUEUED "228 OK TONE QUEUED\r\n"
 
 #define OK_RECEIVE_DATA                                "230 OK RECEIVING 
DATA\r\n"
 #define OK_BYE                                 "231 HAPPY HACKING\r\n"
@@ -102,6 +103,11 @@
 #define ERR_VOLUME_TOO_HIGH                      "413 ERR PITCH TOO HIGH\r\n"
 #define ERR_VOLUME_TOO_LOW                       "414 ERR PITCH TOO LOW\r\n"
 
+#define ERR_TONE_FREQ_TOO_LOW "415 TONE FREQUENCY TOO LOW\r\n"
+#define ERR_TONE_FREQ_TOO_HIGH "416 TONE FREQUENCY TOO HIGH\r\n"
+#define ERR_TONE_DUR_TOO_LOW "417 TONE DURATION TOO LOW\r\n"
+#define ERR_TONE_DUR_TOO_HIGH "418 TONE DURATION TOO HIGH\r\n"
+
 #define ERR_INTERNAL                           "300 ERR INTERNAL\r\n"
 #define ERR_COULDNT_SET_PRIORITY                "301 ERR COULDNT SET 
PRIORITY\r\n"
 #define ERR_COULDNT_SET_LANGUAGE                "302 ERR COULDNT SET 
LANGUAGE\r\n"
diff --git a/src/server/output.c b/src/server/output.c
index 24db70c..47bcfce 100644
--- a/src/server/output.c
+++ b/src/server/output.c
@@ -547,6 +547,7 @@ output_speak(TSpeechDMessage *msg)
         case MSGTYPE_SOUND_ICON: SEND_CMD("SOUND_ICON"); break;
         case MSGTYPE_CHAR: SEND_CMD("CHAR"); break;
         case MSGTYPE_KEY: SEND_CMD("KEY"); break;
+        case MSGTYPE_TONE: SEND_CMD("TONE"); break;
         default: MSG(2,"Invalid message type in output_speak()!");
         }
 
diff --git a/src/server/parse.c b/src/server/parse.c
index 09806c3..227fbdb 100644
--- a/src/server/parse.c
+++ b/src/server/parse.c
@@ -36,6 +36,10 @@
 #include "sem_functions.h"
 #include "output.h"
 
+/* Prototypes. */
+static char* parse_tone(const char* buf, const int bytes,
+                       const int fd, const TSpeechDSock *speechd_socket);
+
 /*
   Parse() receives input data and parses them. It can
   be either command or data to speak. If it's command, it
@@ -107,6 +111,7 @@ parse(const char *buf, const int bytes, const int fd)
         CHECK_SSIP_COMMAND("sound_icon", parse_snd_icon, BLOCK_OK);
         CHECK_SSIP_COMMAND("char", parse_char, BLOCK_OK);
         CHECK_SSIP_COMMAND("key", parse_key, BLOCK_OK)
+        CHECK_SSIP_COMMAND("tone", parse_tone, BLOCK_OK);
         CHECK_SSIP_COMMAND("list", parse_list, BLOCK_NO);
         CHECK_SSIP_COMMAND("get", parse_get, BLOCK_NO);
         CHECK_SSIP_COMMAND("help", parse_help, BLOCK_NO);              
@@ -810,6 +815,49 @@ parse_key(const char* buf, const int bytes, const int fd, 
const TSpeechDSock *sp
     return parse_general_event(buf, bytes, fd, speechd_socket, MSGTYPE_KEY);
 }
 
+#define TONE_FREQ_MIN 50
+#define TONE_FREQ_MAX 5000
+#define TONE_DUR_MIN 50
+#define TONE_DUR_MAX 10000
+
+static char*
+parse_tone(const char* buf, const int bytes, const int fd,
+          const TSpeechDSock *speechd_socket)
+{
+    TSpeechDMessage *new_message;
+    const char *reply = OK_TONE_QUEUED;
+    int frequency;
+    int duration;
+    GET_PARAM_INT(frequency, 1);
+    GET_PARAM_INT(duration, 2);
+
+    if (frequency < TONE_FREQ_MIN)
+       reply = ERR_TONE_FREQ_TOO_LOW;
+    else if (frequency > TONE_FREQ_MAX)
+       reply = ERR_TONE_FREQ_TOO_HIGH;
+    else if (duration < TONE_DUR_MIN)
+       reply = ERR_TONE_DUR_TOO_LOW;
+    else if (duration > TONE_DUR_MAX)
+       reply = ERR_TONE_DUR_TOO_HIGH;
+    else {
+       new_message = g_malloc(sizeof(TSpeechDMessage));
+       new_message->buf = g_strdup_printf("%d %d", frequency, duration);
+       new_message->bytes = strlen(new_message->buf);
+       if (queue_message(new_message, fd, 1, MSGTYPE_TONE,
+                         speechd_socket->inside_block) == 0) {
+           if (SPEECHD_DEBUG)
+               FATAL("Couldn't queue message\n");
+           MSG(2, "Error: couldn't queue message!\n");
+           reply = ERR_INTERNAL;
+           g_free(new_message->buf);
+           g_free(new_message);
+       }
+    }
+
+    return g_strdup(reply);
+}
+
+
 char*
 parse_list(const char* buf, const int bytes, const int fd, const TSpeechDSock 
*speechd_socket)
 {
@@ -962,6 +1010,7 @@ parse_help(const char* buf, const int bytes, const int fd, 
const TSpeechDSock *s
             C_OK_HELP"-  KEY             -- say a combination of keys \r\n"
             C_OK_HELP"-  CHAR            -- say a character \r\n"
             C_OK_HELP"-  SOUND_ICON      -- execute a sound icon \r\n"
+            C_OK_HELP"-  TONE      -- play a tone \r\n"
             C_OK_HELP"-  SET             -- set a parameter \r\n"
             C_OK_HELP"-  GET             -- get a current parameter \r\n"
             C_OK_HELP"-  LIST            -- list available arguments \r\n"
-- 
1.7.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]