From:        newsham@lava.net (Tim Newsham)
To:          speak-freely@fourmilab.ch
Subject:     patch for signals and push-to-talk
Date:        Thu, 9 Apr 1998 17:49:10 -1000 (HST)


Hi,

    I wrote a patch to let you toggle talkign versus pause mode
via signals.  In the process I also cleaned up the push to talk via
keyboard code a little (I didn't like how it was previously).  I
tested that it actually toggles mode, but I didn't test this live
(with a speaker hooked up to the receiver),  so let me know if
you have problems.

As always, my diffs are public domain,  use em as you wish, steal em,
put your name on it, I don't care.  

To use, run sfmike with the -X option.  From another program, lookup
the pid of the program (you can get it from the shell after you invoked
sfmike, or by ps) and "kill -USR1 pid" to toggle talk/pause mode.
As before "kill pid" will stop sfmike.

Enjoy.

                                         Tim N.


--- mike.c.bak  Thu Apr  9 16:59:08 1998
+++ mike.c      Thu Apr  9 17:39:53 1998
@@ -41,11 +41,6 @@
 static int squelch = 0;              /* Squelch level if > 0 */
 static int sqdelay = 12000;          /* Samples to delay before squelch */
 static int sqwait = 0;               /* Squelch delay countdown */
-#ifdef PUSH_TO_TALK
-static int push = TRUE;              /* Push to talk mode */
-static int talking = FALSE;          /* Push to talk button state */
-static int rawmode = FALSE;          /* Is terminal in raw mode ? */
-#endif
 static int ring = FALSE;             /* Force speaker & level on next pkt ? */
 static int rtp = FALSE;              /* Use Internet Real-Time Protocol */
 static int vat = FALSE;              /* Use VAT protocol */
@@ -97,6 +92,114 @@
 extern int HPTermHookChar;
 #endif
 
+
+#ifdef PUSH_TO_TALK
+/* values for `push' */
+#define PUSH_MODE_OFF  0
+#define PUSH_MODE_KEY  1
+#define PUSH_MODE_SIG  2
+
+static void exiting(void);
+
+static int push = PUSH_MODE_KEY;      /* key mode */
+static int talking = FALSE;          /* Push to talk button state */
+static int rawmode = FALSE;          /* Is terminal in raw mode ? */
+static int push_sig_mode = 0;         /* last requested mode according to sig*/
+
+/*  TERMCHAR  --  Check for special characters from console when
+                 in raw mode.  */
+static void termchar(ch)    
+  int ch;
+{
+#define Ctrl(x) ((x) - '@')
+    if (ch == 'q' || ch == 'Q' || ch == 27 ||
+       ch == Ctrl('C') || ch == Ctrl('D')) {
+       exiting();
+    }
+}
+
+static void
+push_sig_handler(int sig)
+{
+    push_sig_mode = !push_sig_mode;
+    return;
+}
+
+static void
+init_push()
+{
+    talking = FALSE;
+    spurt = FALSE;
+    if(push == PUSH_MODE_KEY) {
+       char c;
+       int l;
+
+       fprintf(stderr,
+           "Space bar switches talk/pause, Esc or \"q\" to quit\nPause: ");
+       fflush(stderr);
+       initscr();
+       noecho();
+       cbreak();
+       rawmode = TRUE;
+    }
+    if(push == PUSH_MODE_SIG) {
+        signal(SIGUSR1, push_sig_handler);
+        push_sig_mode = talking;
+       fprintf(stderr, "SIGUSR switches talk/pause\nPause: ");
+    }
+    return;
+}
+
+/* return 0 for success, -1 for error */
+static int
+wait_push()
+{
+    if(push == PUSH_MODE_KEY) {
+       char c;
+       int rlen;
+
+       rlen = read(fileno(stdin), &c, 1);
+#ifdef HEWLETT_PACKARD
+        if(HPTermHookChar) {
+            c = HPTermHookChar;
+            rlen = 1;
+        }
+#endif
+        if(rlen == 1) {
+           termchar(c);
+           talking = !talking;
+            return 0;
+        } else {
+            if(errno == EINTR)
+                return 0;
+            else
+                return -1;
+        }
+    }
+
+    if(push == PUSH_MODE_SIG) {
+        /* keep looping until we get our sig (which interrupts sleep) */
+        while(push_sig_mode == talking) {
+            sleep(100);
+        }
+        talking = push_sig_mode;
+        return 0;
+    }
+}
+
+static void
+destroy_push()
+{
+    if (rawmode) {
+       fprintf(stderr, "\r      \r");
+       fcntl(fileno(stdin), F_SETFL, 0);
+       nocbreak();
+       echo();
+       endwin();
+    }
+}
+#endif /*PUSH_TO_TALK*/
+
 #define ucase(x)    (islower(x) ? toupper(x) : (x))
 
 /*  ULARM  --  Wrapper for setitimer() that looks like alarm()
@@ -807,13 +910,7 @@
     struct destination *d;
 
 #ifdef PUSH_TO_TALK
-    if (rawmode) {
-       fprintf(stderr, "\r      \r");
-       fcntl(fileno(stdin), F_SETFL, 0);
-       nocbreak();
-       echo();
-       endwin();
-    }
+    destroy_push();
 #endif
 
     if (rtp) {
@@ -856,18 +953,6 @@
     exit(0);
 }
 
-/*  TERMCHAR  --  Check for special characters from console when
-                 in raw mode.  */
-
-static void termchar(ch)    
-  int ch;
-{
-#define Ctrl(x) ((x) - '@')
-    if (ch == 'q' || ch == 'Q' || ch == 27 ||
-       ch == Ctrl('C') || ch == Ctrl('D')) {
-       exiting();
-    }
-}
 
 /*  SENDFILE  --  Send a file or, if the file name is NULL or a
                  single period, send real-time sound input. */
@@ -1125,32 +1210,12 @@
            /* Send real-time audio. */
 
 #ifdef PUSH_TO_TALK
-       if (push) {
-           char c;
-           int l;
-
-           fprintf(stderr,
-               "Space bar switches talk/pause, Esc or \"q\" to quit\nPause: ");
-           fflush(stderr);
-           initscr();
-           noecho();
-           cbreak();
-           rawmode = TRUE;
-           while (TRUE) {
-               if (l = read(fileno(stdin), &c, 1) == 1 || errno != EINTR) {
-                   break;
-               }
-           }   
-           if (l != 1) {
-               perror("waiting for first Pause/Talk character");
-           }
-           termchar(c);
+            init_push();
+            wait_push();
 /*         fprintf(stderr, "\rTalk:  "); */
            fprintf(stderr, squelch > 0 ? "\rQuiet:  " : "\rTalk:   ");
            fcntl(fileno(stdin), F_SETFL, O_NDELAY);
-           talking = TRUE;
            spurt = TRUE;
-       }
 #endif
 
        /* Send real-time sound. */
@@ -1185,57 +1250,38 @@
 
 #ifdef PUSH_TO_TALK
            while (push) {
-               char c;
-               int rlen;
+                int ret;
 
-               if ((rlen = read(fileno(stdin), &c, 1)) > 0
-#ifdef HEWLETT_PACKARD
-                   || HPTermHookChar
-#endif
-                  ) {
-#ifdef HEWLETT_PACKARD
-                   c = HPTermHookChar;
-#endif
-                   termchar(c);
-                   talking = !talking;
-                   fflush(stderr);
+                ret = wait_push();
+                if(ret == -1)
+                    break;
+               fflush(stderr);
 #ifdef HALF_DUPLEX
 
-                   /* For half-duplex, acquire and release the
-                      audio device at each transition.  This lets
-                      us mute the output only while in Talk mode. */
-
-                   if (talking) {
-                       if (!getaudio()) {
-                           fprintf(stderr, "Audio device busy.\n");
-                           talking = FALSE;
-                       }
-                   } else {
-                       freeaudio();
+               /* For half-duplex, acquire and release the
+                  audio device at each transition.  This lets
+                  us mute the output only while in Talk mode. */
+
+               if (talking) {
+                   if (!getaudio()) {
+                       fprintf(stderr, "Audio device busy.\n");
+                       talking = FALSE;
                    }
+               } else {
+                   freeaudio();
+               }
 #endif
-                   fprintf(stderr, talking ? (squelch > 0 ?
-                           "\rQuiet: " : "\rTalk:   ") : "\rPause: ");
-                   fcntl(fileno(stdin), F_SETFL, talking ? O_NDELAY : 0);
-                   if (talking) {
-                       spurt = TRUE;
-                       /* Discard all backlog sound input. */
-                       soundflush();
-                   } else {
-                       sqwait = 0;   /* Reset squelch delay */
-                   }
-                   break;
+               fprintf(stderr, talking ? (squelch > 0 ?
+                       "\rQuiet: " : "\rTalk:   ") : "\rPause: ");
+               fcntl(fileno(stdin), F_SETFL, talking ? O_NDELAY : 0);
+               if (talking) {
+                   spurt = TRUE;
+                   /* Discard all backlog sound input. */
+                   soundflush();
                } else {
-/*
-if (rlen == -1) {
-perror("Read poll"); fflush(stderr);
-}
-*/
-                   if (rlen == -1 && errno == EINTR) {
-                       continue;
-                   }
-                   break;
+                   sqwait = 0;   /* Reset squelch delay */
                }
+               break;
            }
 #endif
 
@@ -1447,6 +1493,7 @@
 #ifdef PUSH_TO_TALK
     V fprintf(stderr, "          -A         Always transmit unless squelched\n");
     V fprintf(stderr, "     *    -B         Push to talk using keyboard\n");
+    V fprintf(stderr, "     *    -X         Push to talk using signals\n");
 #endif
     V fprintf(stderr, "          -C         Compress subsequent sound\n");
     V fprintf(stderr, "          -D         Enable debug output\n");
@@ -1575,13 +1622,16 @@
 
 #ifdef PUSH_TO_TALK
                case 'A':             /* -A  --  Always transmit (no push to talk) */
-                   push = FALSE;
+                   push = PUSH_MODE_OFF;
                    break;
 
                case 'B':             /* -B  -- Push to talk (button) */
                    if (isatty(fileno(stdin))) {
-                       push = TRUE;
+                       push = PUSH_MODE_KEY;
                    }
+                   break;
+               case 'X':             /* -X  --  push to talk (with sigs) */
+                   push = PUSH_MODE_SIG;
                    break;
 #endif
 



                      * * *

To unsubscribe from this mailing list, send E-mail containing
the word "unsubscribe" in the message body (*not* as the
Subject) to speak-freely-request@fourmilab.ch

