From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: "Ben Key" Newsgroups: gmane.emacs.devel Subject: New and improved patch for Windows implementation of play-sound-internal Date: Tue, 29 Oct 2002 00:27:42 -0500 Sender: emacs-devel-admin@gnu.org Message-ID: <001101c27f0b$e7d63c20$6401a8c0@GODDESS> Reply-To: NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0012_01C27EE1.FF003420" X-Trace: main.gmane.org 1035870214 16134 80.91.224.249 (29 Oct 2002 05:43:34 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Tue, 29 Oct 2002 05:43:34 +0000 (UTC) Cc: Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 186PA5-0004Bz-00 for ; Tue, 29 Oct 2002 06:43:33 +0100 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 186PEX-0003Ne-00 for ; Tue, 29 Oct 2002 06:48:09 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10) id 186P78-0001kG-00; Tue, 29 Oct 2002 00:40:30 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10) id 186P6R-00015K-00 for emacs-devel@gnu.org; Tue, 29 Oct 2002 00:39:47 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10) id 186P6N-0000zw-00 for emacs-devel@gnu.org; Tue, 29 Oct 2002 00:39:45 -0500 Original-Received: from gnudist.gnu.org ([199.232.41.7]) by monty-python.gnu.org with esmtp (Exim 4.10) id 186P6J-0000tm-00; Tue, 29 Oct 2002 00:39:39 -0500 Original-Received: from smtp-server1.tampabay.rr.com ([65.32.1.34]) by gnudist.gnu.org with esmtp (Exim 4.10) id 186OuY-0002TX-00; Tue, 29 Oct 2002 00:27:30 -0500 Original-Received: from GODDESS (6535194hfc48.tampabay.rr.com [65.35.194.48]) by smtp-server1.tampabay.rr.com (8.12.2/8.12.2) with SMTP id g9T5RRMl027490; Tue, 29 Oct 2002 00:27:27 -0500 (EST) Original-To: X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook CWS, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 Importance: Normal Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:8871 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:8871 This is a multi-part message in MIME format. ------=_NextPart_000_0012_01C27EE1.FF003420 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Attached to this Email message is an updated version of my patch for GNU Emacs to provide a partial Windows compatible implementation of play-sound-internal. This patch contains two changes from my previous version: 1) I fixed a warning dealing with incompatible pointer types that occurred when compiling with MinGW 2.0. 2) I fixed a bug that caused play-sound-internal to fail unless you specified the full path and file name of the sound file. In other words, you could not do the following M-x play-sound-internal RET ~/SOUNDS/start.wav RET Any attempt to call play-sound-file (and thus play-sound-internal) without specifying the full path and file name would lead to the error message "The open mciSendString command failed to open the specified sound file" being displayed. Now play-sound-internal attempts to obtain the full path and file name if only a partial file name was specified using the function expand-file-name (or Fexpand_file_name when called from C source code). Thus far I have tested this patch on Windows XP using MSVC 6.0 and MinGW 2.0. Tomorrow I will test this patch on GNU/Linux to make certain I did not inadvertently cause a compilation error under that platform (I cannot do it tonight since I am once again reinstalling GNU/Linux on my other computer. Hopefully this time I know what I am doing and will not make any more stupid mistakes!). ------=_NextPart_000_0012_01C27EE1.FF003420 Content-Type: application/octet-stream; name="emacs-21.3.50-w32-play-sound.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="emacs-21.3.50-w32-play-sound.diff" --- _21.3/nt/nmake.defs 2002-01-04 09:04:53.000000000 -0500=0A= +++ 21.3/nt/nmake.defs 2002-10-28 21:01:48.000000000 -0500=0A= @@ -123,6 +123,7 @@=0A= SHELL32 =3D shell32.lib USER32 =3D user32.lib WSOCK32 =3D wsock32.lib +WINMM =3D winmm.lib=0A= =20 !ifdef NOOPT DEBUG_CFLAGS =3D -DEMACSDEBUG --- _21.3/nt/gmake.defs 2002-01-04 09:04:26.000000000 -0500=0A= +++ 21.3/nt/gmake.defs 2002-10-28 21:01:48.000000000 -0500=0A= @@ -166,6 +166,7 @@=0A= SHELL32 =3D -lshell32=0A= USER32 =3D -luser32=0A= WSOCK32 =3D -lwsock32=0A= +WINMM =3D -lwinmm=0A= =0A= ifdef NOOPT=0A= DEBUG_CFLAGS =3D -DEMACSDEBUG=0A= --- _21.3/src/makefile.w32-in 2002-09-04 02:20:50.000000000 -0400=0A= +++ 21.3/src/makefile.w32-in 2002-10-28 21:01:48.000000000 -0500=0A= @@ -94,6 +94,7 @@=0A= $(BLD)/regex.$(O) \=0A= $(BLD)/scroll.$(O) \=0A= $(BLD)/search.$(O) \=0A= + $(BLD)/sound.$(O) \=0A= $(BLD)/syntax.$(O) \=0A= $(BLD)/sysdep.$(O) \=0A= $(BLD)/term.$(O) \=0A= @@ -133,6 +134,7 @@=0A= $(TLIB1) \=0A= $(TLIBW32) \=0A= $(TLASTLIB) \=0A= + $(WINMM) \=0A= $(ADVAPI32) \=0A= $(GDI32) \=0A= $(COMDLG32) \=0A= @@ -1094,6 +1096,13 @@=0A= $(SRC)/w32bdf.h \=0A= $(SRC)/w32gui.h=0A= =0A= +$(BLD)/sound.$(O) : \=0A= + $(SRC)/sound.c \=0A= + $(SRC)/lisp.h \=0A= + $(SRC)/dispextern.h \=0A= + $(SRC)/atimer.h \=0A= + $(SRC)/syssignal.h=0A= +=0A= $(BLD)/strftime.$(O) : \=0A= $(SRC)/strftime.c \=0A= $(EMACS_ROOT)/src/s/ms-w32.h \=0A= --- _21.3/src/s/ms-w32.h 2002-05-03 16:42:33.000000000 -0400=0A= +++ 21.3/src/s/ms-w32.h 2002-10-28 21:01:48.000000000 -0500=0A= @@ -217,6 +217,7 @@=0A= #define MAXPATHLEN _MAX_PATH=0A= #endif=0A= =0A= +#define HAVE_SOUND 1=0A= #define LISP_FLOAT_TYPE 1=0A= =0A= #undef HAVE_SYS_SELECT_H=0A= --- _21.3/src/sound.c 2002-07-19 10:27:20.000000000 -0400=0A= +++ 21.3/src/sound.c 2002-10-28 21:53:08.000000000 -0500=0A= @@ -21,10 +21,26 @@=0A= /* Written by Gerd Moellmann . Tested with Luigi's=0A= driver on FreeBSD 2.2.7 with a SoundBlaster 16. */=0A= =0A= +/*=0A= + Modified by Ben Key to add a partial=0A= + implementation of the play-sound specification for Windows.=0A= +=0A= + Notes:=0A= + In the Windows implementation of play-sound-internal only the=0A= + :file and :volume keywords are supported. The :device keyword,=0A= + if present, is ignored. The :data keyword, if present, will=0A= + cause an error to be generated.=0A= +=0A= + The Windows implementation of play-sound is implemented via the=0A= + Win32 API functions mciSendString, waveOutGetVolume, and=0A= + waveOutGetVolume which are exported by Winmm.dll.=0A= +*/=0A= +=0A= #include =0A= =0A= #if defined HAVE_SOUND=0A= =0A= +/* BEGIN: Common Includes */=0A= #include =0A= #include =0A= #include =0A= @@ -34,6 +50,11 @@=0A= #include "atimer.h"=0A= #include =0A= #include "syssignal.h"=0A= +/* END: Common Includes */=0A= +=0A= +=0A= +/* BEGIN: Non Windows Includes */=0A= +#ifndef WINDOWSNT=0A= =0A= #ifndef MSDOS=0A= #include =0A= @@ -51,12 +72,55 @@=0A= #ifdef HAVE_SOUNDCARD_H=0A= #include =0A= #endif=0A= +/* END: Non Windows Includes */=0A= +=0A= +#else /* WINDOWSNT */=0A= +=0A= +/* BEGIN: Windows Specific Includes */=0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +/* END: Windows Specific Includes */=0A= +=0A= +#endif /* WINDOWSNT */=0A= +=0A= +/* BEGIN: Common Definitions */=0A= +#define abs(X) ((X) < 0 ? -(X) : (X))=0A= +=0A= +/* Symbols. */=0A= +=0A= +extern Lisp_Object QCfile, QCdata;=0A= +Lisp_Object QCvolume, QCdevice;=0A= +Lisp_Object Qsound;=0A= +Lisp_Object Qplay_sound_functions;=0A= +=0A= +/* Indices of attributes in a sound attributes vector. */=0A= +=0A= +enum sound_attr=0A= +{=0A= + SOUND_FILE,=0A= + SOUND_DATA,=0A= + SOUND_DEVICE,=0A= + SOUND_VOLUME,=0A= + SOUND_ATTR_SENTINEL=0A= +};=0A= +=0A= +static void sound_perror P_ ((char *));=0A= +static void sound_warning P_ ((char *));=0A= +static int parse_sound P_ ((Lisp_Object, Lisp_Object *));=0A= +=0A= +/* END: Common Definitions */=0A= +=0A= +/* BEGIN: Non Windows Definitions */=0A= +#ifndef WINDOWSNT=0A= =0A= #ifndef DEFAULT_SOUND_DEVICE=0A= #define DEFAULT_SOUND_DEVICE "/dev/dsp"=0A= #endif=0A= =0A= -#define abs(X) ((X) < 0 ? -(X) : (X))=0A= =0A= /* Structure forward declarations. */=0A= =0A= @@ -203,24 +267,6 @@=0A= void (* play) P_ ((struct sound *s, struct sound_device *sd));=0A= };=0A= =0A= -/* Indices of attributes in a sound attributes vector. */=0A= -=0A= -enum sound_attr=0A= -{=0A= - SOUND_FILE,=0A= - SOUND_DATA,=0A= - SOUND_DEVICE,=0A= - SOUND_VOLUME,=0A= - SOUND_ATTR_SENTINEL=0A= -};=0A= -=0A= -/* Symbols. */=0A= -=0A= -extern Lisp_Object QCfile, QCdata;=0A= -Lisp_Object QCvolume, QCdevice;=0A= -Lisp_Object Qsound;=0A= -Lisp_Object Qplay_sound_functions;=0A= -=0A= /* These are set during `play-sound-internal' so that sound_cleanup has=0A= access to them. */=0A= =0A= @@ -235,9 +281,6 @@=0A= static void vox_choose_format P_ ((struct sound_device *, struct sound = *));=0A= static void vox_init P_ ((struct sound_device *));=0A= static void vox_write P_ ((struct sound_device *, const char *, int));=0A= -static void sound_perror P_ ((char *));=0A= -static void sound_warning P_ ((char *));=0A= -static int parse_sound P_ ((Lisp_Object, Lisp_Object *));=0A= static void find_sound_type P_ ((struct sound *));=0A= static u_int32_t le2hl P_ ((u_int32_t));=0A= static u_int16_t le2hs P_ ((u_int16_t));=0A= @@ -251,12 +294,22 @@=0A= static u_int16_t be2hs P_ ((u_int16_t));=0A= #endif=0A= =0A= +/* END: Non Windows Definitions */=0A= +#else /* WINDOWSNT */=0A= +=0A= +/* BEGIN: Windows Specific Definitions */=0A= +static int do_play_sound P_ ((const char *,unsigned long));=0A= +/*=0A= + END: Windows Specific Definitions */=0A= +#endif /* WINDOWSNT */=0A= =0A= =0C=0A= /***********************************************************************=0A= General=0A= = ***********************************************************************/=0A= =0A= +/* BEGIN: Common functions */=0A= +=0A= /* Like perror, but signals an error. */=0A= =0A= static void=0A= @@ -327,10 +380,21 @@=0A= attrs[SOUND_DEVICE] =3D Fplist_get (sound, QCdevice);=0A= attrs[SOUND_VOLUME] =3D Fplist_get (sound, QCvolume);=0A= =0A= +#ifndef WINDOWSNT=0A= /* File name or data must be specified. */=0A= if (!STRINGP (attrs[SOUND_FILE])=0A= && !STRINGP (attrs[SOUND_DATA]))=0A= return 0;=0A= +#else /* WINDOWSNT */=0A= + /*=0A= + Data is not supported in Windows. Therefore a=0A= + File name MUST be supplied.=0A= + */=0A= + if (!STRINGP(attrs[SOUND_FILE]))=0A= + {=0A= + return 0;=0A= + }=0A= +#endif /* WINDOWSNT */=0A= =0A= /* Volume must be in the range 0..100 or unspecified. */=0A= if (!NILP (attrs[SOUND_VOLUME]))=0A= @@ -351,14 +415,23 @@=0A= return 0;=0A= }=0A= =0A= +#ifndef WINDOWSNT=0A= /* Device must be a string or unspecified. */=0A= if (!NILP (attrs[SOUND_DEVICE])=0A= && !STRINGP (attrs[SOUND_DEVICE]))=0A= return 0;=0A= -=0A= +#endif /* WINDOWSNT */=0A= + /*=0A= + Since device is ignored in Windows, it does not matter=0A= + what it is.=0A= + */=0A= return 1;=0A= }=0A= =0A= +/* END: Common functions */=0A= +=0A= +/* BEGIN: Non Windows functions */=0A= +#ifndef WINDOWSNT=0A= =0A= /* Find out the type of the sound file whose file descriptor is FD.=0A= S is the sound file structure to fill in. */=0A= @@ -389,105 +462,6 @@=0A= return Qnil;=0A= }=0A= =0A= -=0A= -DEFUN ("play-sound-internal", Fplay_sound_internal, = Splay_sound_internal, 1, 1, 0,=0A= - doc: /* Play sound SOUND.=0A= -=0A= -Internal use only, use `play-sound' instead. */)=0A= - (sound)=0A= - Lisp_Object sound;=0A= -{=0A= - Lisp_Object attrs[SOUND_ATTR_SENTINEL];=0A= - Lisp_Object file;=0A= - struct gcpro gcpro1, gcpro2;=0A= - struct sound_device sd;=0A= - struct sound s;=0A= - Lisp_Object args[2];=0A= - int count =3D SPECPDL_INDEX ();=0A= -=0A= - file =3D Qnil;=0A= - GCPRO2 (sound, file);=0A= - bzero (&sd, sizeof sd);=0A= - bzero (&s, sizeof s);=0A= - current_sound_device =3D &sd;=0A= - current_sound =3D &s;=0A= - record_unwind_protect (sound_cleanup, Qnil);=0A= - s.header =3D (char *) alloca (MAX_SOUND_HEADER_BYTES);=0A= -=0A= - /* Parse the sound specification. Give up if it is invalid. */=0A= - if (!parse_sound (sound, attrs))=0A= - error ("Invalid sound specification");=0A= -=0A= - if (STRINGP (attrs[SOUND_FILE]))=0A= - {=0A= - /* Open the sound file. */=0A= - s.fd =3D openp (Fcons (Vdata_directory, Qnil),=0A= - attrs[SOUND_FILE], Qnil, &file, Qnil);=0A= - if (s.fd < 0)=0A= - sound_perror ("Could not open sound file");=0A= -=0A= - /* Read the first bytes from the file. */=0A= - s.header_size =3D emacs_read (s.fd, s.header, = MAX_SOUND_HEADER_BYTES);=0A= - if (s.header_size < 0)=0A= - sound_perror ("Invalid sound file header");=0A= - }=0A= - else=0A= - {=0A= - s.data =3D attrs[SOUND_DATA];=0A= - s.header_size =3D min (MAX_SOUND_HEADER_BYTES, SBYTES (s.data));=0A= - bcopy (SDATA (s.data), s.header, s.header_size);=0A= - }=0A= -=0A= - /* Find out the type of sound. Give up if we can't tell. */=0A= - find_sound_type (&s);=0A= -=0A= - /* Set up a device. */=0A= - if (STRINGP (attrs[SOUND_DEVICE]))=0A= - {=0A= - int len =3D SCHARS (attrs[SOUND_DEVICE]);=0A= - sd.file =3D (char *) alloca (len + 1);=0A= - strcpy (sd.file, SDATA (attrs[SOUND_DEVICE]));=0A= - }=0A= -=0A= - if (INTEGERP (attrs[SOUND_VOLUME]))=0A= - sd.volume =3D XFASTINT (attrs[SOUND_VOLUME]);=0A= - else if (FLOATP (attrs[SOUND_VOLUME]))=0A= - sd.volume =3D XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;=0A= -=0A= - args[0] =3D Qplay_sound_functions;=0A= - args[1] =3D sound;=0A= - Frun_hook_with_args (2, args);=0A= -=0A= - /* There is only one type of device we currently support, the VOX=0A= - sound driver. Set up the device interface functions for that=0A= - device. */=0A= - vox_init (&sd);=0A= -=0A= - /* Open the device. */=0A= - sd.open (&sd);=0A= -=0A= - /* Play the sound. */=0A= - s.play (&s, &sd);=0A= -=0A= - /* Close the input file, if any. */=0A= - if (!STRINGP (s.data))=0A= - {=0A= - emacs_close (s.fd);=0A= - s.fd =3D -1;=0A= - }=0A= -=0A= - /* Close the device. */=0A= - sd.close (&sd);=0A= -=0A= - /* Clean up. */=0A= - current_sound_device =3D NULL;=0A= - current_sound =3D NULL;=0A= - UNGCPRO;=0A= - unbind_to (count, Qnil);=0A= - return Qnil;=0A= -}=0A= -=0A= -=0C=0A= /***********************************************************************=0A= Byte-order Conversion=0A= = ***********************************************************************/=0A= @@ -555,7 +529,6 @@=0A= =0A= #endif /* 0 */=0A= =0A= -=0C=0A= /***********************************************************************=0A= RIFF-WAVE (*.wav)=0A= = ***********************************************************************/=0A= @@ -645,7 +618,6 @@=0A= }=0A= =0A= =0A= -=0C=0A= /***********************************************************************=0A= Sun Audio (*.au)=0A= = ***********************************************************************/=0A= @@ -735,7 +707,6 @@=0A= }=0A= =0A= =0A= -=0C=0A= /***********************************************************************=0A= Voxware Driver Interface=0A= = ***********************************************************************/=0A= @@ -909,7 +880,6 @@=0A= sd->write =3D vox_write;=0A= }=0A= =0A= -=0A= /* Write NBYTES bytes from BUFFER to device SD. */=0A= =0A= static void=0A= @@ -923,7 +893,231 @@=0A= sound_perror ("Error writing to sound device");=0A= }=0A= =0A= +/* END: Non Windows functions */=0A= +#else /* WINDOWSNT */=0A= +=0A= +/* BEGIN: Windows specific functions */=0A= =0A= +static int=0A= +do_play_sound(psz_file,ui_volume)=0A= + const char * psz_file;=0A= + unsigned long ui_volume;=0A= +{=0A= + int i_result=3D0;=0A= + MCIERROR mci_error=3D0;=0A= + char sz_cmd_buf[520]=3D{0};=0A= + char sz_ret_buf[520]=3D{0};=0A= + MMRESULT mm_result=3DMMSYSERR_NOERROR;=0A= + unsigned long ui_volume_org=3D0;=0A= + BOOL b_reset_volume=3DFALSE;=0A= + memset(sz_cmd_buf,0,sizeof(sz_cmd_buf));=0A= + memset(sz_ret_buf,0,sizeof(sz_ret_buf));=0A= + sprintf(=0A= + sz_cmd_buf,=0A= + "open \"%s\" alias GNUEmacs_PlaySound_Device wait",=0A= + psz_file);=0A= + mci_error=3DmciSendString(sz_cmd_buf,sz_ret_buf,520,NULL);=0A= + if (mci_error!=3D0)=0A= + {=0A= + sound_warning(=0A= + "The open mciSendString command failed to open\n"=0A= + "the specified sound file");=0A= + i_result=3D(int)mci_error;=0A= + return i_result;=0A= + }=0A= + if (ui_volume>0 && ui_volume!=3DUINT_MAX)=0A= + {=0A= + = mm_result=3DwaveOutGetVolume((HWAVEOUT)WAVE_MAPPER,&ui_volume_org);=0A= + if (mm_result=3D=3DMMSYSERR_NOERROR)=0A= + {=0A= + b_reset_volume=3DTRUE;=0A= + mm_result=3DwaveOutSetVolume((HWAVEOUT)WAVE_MAPPER,ui_volume);=0A= + if (mm_result!=3DMMSYSERR_NOERROR)=0A= + {=0A= + sound_warning(=0A= + "waveOutSetVolume failed to set the volume level\n"=0A= + "of the WAVE_MAPPER device.\n"=0A= + "As a result, the user selected volume level will\n"=0A= + "not be used.");=0A= + }=0A= + }=0A= + else=0A= + {=0A= + sound_warning(=0A= + "waveOutGetVolume failed to obtain the original\n"=0A= + "volume level of the WAVE_MAPPER device.\n"=0A= + "As a result, the user selected volume level will\n"=0A= + "not be used.");=0A= + }=0A= + }=0A= + memset(sz_cmd_buf,0,sizeof(sz_cmd_buf));=0A= + memset(sz_ret_buf,0,sizeof(sz_ret_buf));=0A= + strcpy(sz_cmd_buf,"play GNUEmacs_PlaySound_Device wait");=0A= + mci_error=3DmciSendString(sz_cmd_buf,sz_ret_buf,520,NULL);=0A= + if (mci_error!=3D0)=0A= + {=0A= + sound_warning(=0A= + "The play mciSendString command failed to play the\n"=0A= + "opened sound file.");=0A= + i_result=3D(int)mci_error;=0A= + }=0A= + memset(sz_cmd_buf,0,sizeof(sz_cmd_buf));=0A= + memset(sz_ret_buf,0,sizeof(sz_ret_buf));=0A= + strcpy(sz_cmd_buf,"close GNUEmacs_PlaySound_Device wait");=0A= + mci_error=3DmciSendString(sz_cmd_buf,sz_ret_buf,520,NULL);=0A= + if (b_reset_volume=3D=3DTRUE)=0A= + {=0A= + mm_result=3DwaveOutSetVolume((HWAVEOUT)WAVE_MAPPER,ui_volume_org);=0A= + if (mm_result!=3DMMSYSERR_NOERROR)=0A= + {=0A= + sound_warning(=0A= + "waveOutSetVolume failed to reset the original volume\n"=0A= + "level of the WAVE_MAPPER device.");=0A= + }=0A= + }=0A= + return i_result;=0A= +}=0A= +=0A= +/* END: Windows specific functions */=0A= +=0A= +#endif /* WINDOWSNT */=0A= +=0A= +=0A= +DEFUN ("play-sound-internal", Fplay_sound_internal, = Splay_sound_internal, 1, 1, 0,=0A= + doc: /* Play sound SOUND.=0A= +=0A= +Internal use only, use `play-sound' instead.\n */)=0A= + (sound)=0A= + Lisp_Object sound;=0A= +{=0A= + Lisp_Object attrs[SOUND_ATTR_SENTINEL];=0A= + int count =3D SPECPDL_INDEX ();=0A= +=0A= +#ifndef WINDOWSNT=0A= + Lisp_Object file;=0A= + struct gcpro gcpro1, gcpro2;=0A= + struct sound_device sd;=0A= + struct sound s;=0A= + Lisp_Object args[2];=0A= +#else /* WINDOWSNT */=0A= + int len=3D0;=0A= + Lisp_Object lo_file=3D{0};=0A= + char * psz_file=3DNULL;=0A= + unsigned long ui_volume_tmp=3DUINT_MAX;=0A= + unsigned long ui_volume=3DUINT_MAX;=0A= + int i_result=3D0;=0A= +#endif /* WINDOWSNT */=0A= +=0A= + /* Parse the sound specification. Give up if it is invalid. */=0A= + if (!parse_sound (sound, attrs))=0A= + error ("Invalid sound specification");=0A= +=0A= +#ifndef WINDOWSNT=0A= + file =3D Qnil;=0A= + GCPRO2 (sound, file);=0A= + bzero (&sd, sizeof sd);=0A= + bzero (&s, sizeof s);=0A= + current_sound_device =3D &sd;=0A= + current_sound =3D &s;=0A= + record_unwind_protect (sound_cleanup, Qnil);=0A= + s.header =3D (char *) alloca (MAX_SOUND_HEADER_BYTES);=0A= +=0A= + if (STRINGP (attrs[SOUND_FILE]))=0A= + {=0A= + /* Open the sound file. */=0A= + s.fd =3D openp (Fcons (Vdata_directory, Qnil),=0A= + attrs[SOUND_FILE], Qnil, &file, Qnil);=0A= + if (s.fd < 0)=0A= + sound_perror ("Could not open sound file");=0A= +=0A= + /* Read the first bytes from the file. */=0A= + s.header_size =3D emacs_read (s.fd, s.header, = MAX_SOUND_HEADER_BYTES);=0A= + if (s.header_size < 0)=0A= + sound_perror ("Invalid sound file header");=0A= + }=0A= + else=0A= + {=0A= + s.data =3D attrs[SOUND_DATA];=0A= + s.header_size =3D min (MAX_SOUND_HEADER_BYTES, SBYTES (s.data));=0A= + bcopy (SDATA (s.data), s.header, s.header_size);=0A= + }=0A= +=0A= + /* Find out the type of sound. Give up if we can't tell. */=0A= + find_sound_type (&s);=0A= +=0A= + /* Set up a device. */=0A= + if (STRINGP (attrs[SOUND_DEVICE]))=0A= + {=0A= + int len =3D SCHARS (attrs[SOUND_DEVICE]);=0A= + sd.file =3D (char *) alloca (len + 1);=0A= + strcpy (sd.file, SDATA (attrs[SOUND_DEVICE]));=0A= + }=0A= +=0A= + if (INTEGERP (attrs[SOUND_VOLUME]))=0A= + sd.volume =3D XFASTINT (attrs[SOUND_VOLUME]);=0A= + else if (FLOATP (attrs[SOUND_VOLUME]))=0A= + sd.volume =3D XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;=0A= +=0A= + args[0] =3D Qplay_sound_functions;=0A= + args[1] =3D sound;=0A= + Frun_hook_with_args (2, args);=0A= +=0A= + /* There is only one type of device we currently support, the VOX=0A= + sound driver. Set up the device interface functions for that=0A= + device. */=0A= + vox_init (&sd);=0A= +=0A= + /* Open the device. */=0A= + sd.open (&sd);=0A= +=0A= + /* Play the sound. */=0A= + s.play (&s, &sd);=0A= +=0A= + /* Close the input file, if any. */=0A= + if (!STRINGP (s.data))=0A= + {=0A= + emacs_close (s.fd);=0A= + s.fd =3D -1;=0A= + }=0A= +=0A= + /* Close the device. */=0A= + sd.close (&sd);=0A= +=0A= + /* Clean up. */=0A= + current_sound_device =3D NULL;=0A= + current_sound =3D NULL;=0A= + UNGCPRO;=0A= +#else /* WINDOWSNT */=0A= + lo_file=3DFexpand_file_name(attrs[SOUND_FILE],Qnil);=0A= + len=3DXSTRING(lo_file)->size;=0A= + psz_file=3D(char *)alloca(len+1);=0A= + strcpy(psz_file,XSTRING(lo_file)->data);=0A= + if (INTEGERP (attrs[SOUND_VOLUME]))=0A= + {=0A= + ui_volume_tmp=3DXFASTINT(attrs[SOUND_VOLUME]);=0A= + }=0A= + else if (FLOATP(attrs[SOUND_VOLUME]))=0A= + {=0A= + ui_volume_tmp=3D(unsigned = long)XFLOAT_DATA(attrs[SOUND_VOLUME])*100;=0A= + }=0A= + /*=0A= + Based on some experiments I have conducted, a value of 100 or less=0A= + for the sound volume is much too low. You cannot even hear it.=0A= + A value of UINT_MAX indicates that you wish for the sound to played=0A= + at the maximum possible volume. A value of UINT_MAX/2 plays the=0A= + sound at 50% maximum volume. Therefore the value passed to = do_play_sound=0A= + (and thus to waveOutSetVolume must be some fraction of UINT_MAX.=0A= + The following code adjusts the user specified volume level = appropriately.=0A= + */=0A= + if (ui_volume_tmp>0 && ui_volume_tmp<=3D100)=0A= + {=0A= + ui_volume=3Dui_volume_tmp*(UINT_MAX/100);=0A= + }=0A= + i_result=3Ddo_play_sound(psz_file,ui_volume);=0A= +#endif /* WINDOWSNT */=0A= + unbind_to (count, Qnil);=0A= + return Qnil;=0A= +}=0A= =0C=0A= /***********************************************************************=0A= Initialization=0A= ------=_NextPart_000_0012_01C27EE1.FF003420 Content-Type: application/octet-stream; name="dopatch21_3.sh" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dopatch21_3.sh" #!/bin/sh patch --unified --quiet --strip=1 --input=emacs-21.3.50-w32-play-sound.diff ------=_NextPart_000_0012_01C27EE1.FF003420--