A better beep, try 2

David Lee Lambert lamber45 at cse.msu.edu
Wed May 25 12:25:58 CDT 2005


This patch more fully implements the Beep() function.  I've added some 
bounds-checking that wasn't in my previous submission,  and the sound-card 
portion is new.  Note that this patch is against a clean codebase (because 
my previous one hadn't been accepted).

I tested Windows XP, and it obeys dwFreq and dwDur.

PuTTY also obeys the frequency-control code and ignores duration (and 
otherwise behaves well when made to look like a Linux console).

ChangeLog:
  Implement Beep() using the linux console or the default OSS sound-card,
if available;  default implementation obeys dwDur().

-- 
David Lee Lambert (also as4109 at wayne.edu)    cell ph# 586-873-8813
PGP key at http://www.cse.msu.edu/~lamber45/newmail.htm#GPGKey
-------------- next part --------------
--- dlls/kernel/console.c.v1_40	Sat May 21 20:32:33 2005
+++ dlls/kernel/console.c	Wed May 25 12:59:30 2005
@@ -189,13 +189,61 @@
 
 
 /***********************************************************************
- *           Beep   (KERNEL32.@)
+ *           Beep   (KERNEL32.@)  Make noise
+ *
+ * PARAMS
+ *    dwFreq [I]   Frequency of a tone in Hz
+ *    dwDur  [I]   Duration in ms, -1 for indefinite
+ *
+ * This call was originally designed to use the PC speaker;
+ * however, on Win95, frequency and duration were ignored and
+ * the system played a .wav file instead. WinXP restores the
+ * WinNT behaviour of using the speaker.
+ *
  */
 BOOL WINAPI Beep( DWORD dwFreq, DWORD dwDur )
 {
-    static const char beep = '\a';
-    /* dwFreq and dwDur are ignored by Win95 */
-    if (isatty(2)) write( 2, &beep, 1 );
+   int dsp_fd;
+   if (dwDur==-1) {
+		   /* we can't beep forever,  because we need to know
+		    * the duration beforehand to use the following methods. */
+      FIXME("\"beep forever\" not supported");
+
+   } else if (strcmp(getenv("TERM"),"linux")==0 && isatty(2)
+	      && dwDur > 30 && dwFreq > 36 ) {
+		   /* the Linux console supports setting frequency and duration */
+      char szBeep[50];
+
+      if (dwDur > 1999) dwDur = 1999;
+      snprintf(szBeep,50,"\x1B[10;%d]\x1B[11;%d]\a",(int)dwFreq,(int)dwDur);
+      write( 2, szBeep, strlen(szBeep) );
+      usleep(dwDur*1000);
+
+   } else if (dwFreq > 36 && dwFreq < 4000
+	      && -1 != (dsp_fd = open("/dev/dsp",O_WRONLY))) {
+		   /* generate an 8ks/sec,8-bit sample on the fly */
+      int n=dwDur*(8000/1000),i;
+      double x,trim,y;
+      unsigned char *v;
+      v = HeapAlloc( GetProcessHeap(), 0, n);
+      for (i=0; i<n; i++) {
+	 x = i/8000.0;
+	 if (i < 80) { trim=i/80.0; } else if ((n-i)<80) { trim=(n-i)/80.0; } 
+	 else trim=1.0;
+	 y = sin( dwFreq * x * (2*M_PI) ) * trim;
+	 v[i] = (y*126) + 128;   }
+		   /* write it to the OSS or ALSA default device 
+		    * (this is a blocking call; no need to call usleep afterwards) */
+      write(dsp_fd,v,n);
+      HeapFree( GetProcessHeap(), 0, v);
+      close(dsp_fd);
+      
+   } else if (isatty(2)) {
+      static const char beep = '\a';
+      write( 2, &beep, 1 );
+      if (dwDur != -1)
+	 usleep(dwDur*1000);
+   } 
     return TRUE;
 }
 


More information about the wine-patches mailing list