root/src/sound.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sound_perror
  2. sound_warning
  3. parse_sound
  4. string_default
  5. find_sound_type
  6. sound_cleanup
  7. le2hl
  8. le2hs
  9. be2hl
  10. wav_init
  11. wav_play
  12. au_init
  13. au_play
  14. vox_open
  15. vox_configure
  16. vox_close
  17. vox_choose_format
  18. vox_init
  19. vox_write
  20. alsa_sound_perror
  21. alsa_open
  22. alsa_period_size
  23. alsa_configure
  24. alsa_close
  25. alsa_choose_format
  26. alsa_write
  27. snd_error_quiet
  28. alsa_init
  29. do_play_sound
  30. DEFUN
  31. syms_of_sound

     1 /* sound.c -- sound support.
     2 
     3 Copyright (C) 1998-1999, 2001-2023 Free Software Foundation, Inc.
     4 
     5 Author: Gerd Moellmann <gerd@gnu.org>
     6 
     7 This file is part of GNU Emacs.
     8 
     9 GNU Emacs is free software: you can redistribute it and/or modify
    10 it under the terms of the GNU General Public License as published by
    11 the Free Software Foundation, either version 3 of the License, or (at
    12 your option) any later version.
    13 
    14 GNU Emacs is distributed in the hope that it will be useful,
    15 but WITHOUT ANY WARRANTY; without even the implied warranty of
    16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17 GNU General Public License for more details.
    18 
    19 You should have received a copy of the GNU General Public License
    20 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    21 
    22 /* Tested with Luigi's driver on FreeBSD 2.2.7 with a SoundBlaster 16.  */
    23 
    24 /*
    25   Modified by Ben Key <Bkey1@tampabay.rr.com> to add a partial
    26   implementation of the play-sound specification for Windows.
    27 
    28   Notes:
    29   In the Windows implementation of play-sound-internal only the
    30   :file and :volume keywords are supported.  The :device keyword,
    31   if present, is ignored.  The :data keyword, if present, will
    32   cause an error to be generated.
    33 
    34   The Windows implementation of play-sound is implemented via the
    35   Windows API functions mciSendString, waveOutGetVolume, and
    36   waveOutSetVolume which are exported by Winmm.dll.
    37 */
    38 
    39 #include <config.h>
    40 
    41 #if defined HAVE_SOUND
    42 
    43 /* BEGIN: Common Includes */
    44 #include <fcntl.h>
    45 #include <unistd.h>
    46 #include <sys/types.h>
    47 #include <errno.h>
    48 
    49 #include "lisp.h"
    50 #include "atimer.h"
    51 #include "syssignal.h"
    52 /* END: Common Includes */
    53 
    54 
    55 /* BEGIN: Non Windows Includes */
    56 #ifndef WINDOWSNT
    57 
    58 #include <byteswap.h>
    59 
    60 #include <sys/ioctl.h>
    61 
    62 /* FreeBSD has machine/soundcard.h.  Voxware sound driver docs mention
    63    sys/soundcard.h.  So, let's try whatever's there.  */
    64 
    65 #ifdef HAVE_MACHINE_SOUNDCARD_H
    66 #include <machine/soundcard.h>
    67 #endif
    68 #ifdef HAVE_SYS_SOUNDCARD_H
    69 #include <sys/soundcard.h>
    70 #endif
    71 #ifdef HAVE_SOUNDCARD_H
    72 #include <soundcard.h>
    73 #endif
    74 #ifdef HAVE_ALSA
    75 #include <alsa/asoundlib.h>
    76 #endif
    77 
    78 /* END: Non Windows Includes */
    79 
    80 #else /* WINDOWSNT */
    81 
    82 /* BEGIN: Windows Specific Includes */
    83 #include <stdio.h>
    84 #include <limits.h>
    85 #include <mbstring.h>
    86 #include <windows.h>
    87 #include <mmsystem.h>
    88 
    89 #include "coding.h"
    90 #include "w32common.h"
    91 #include "w32.h"
    92 /* END: Windows Specific Includes */
    93 
    94 #endif /* WINDOWSNT */
    95 
    96 /* BEGIN: Common Definitions */
    97 
    98 /* Indices of attributes in a sound attributes vector.  */
    99 
   100 enum sound_attr
   101 {
   102   SOUND_FILE,
   103   SOUND_DATA,
   104   SOUND_DEVICE,
   105   SOUND_VOLUME,
   106   SOUND_ATTR_SENTINEL
   107 };
   108 
   109 /* END: Common Definitions */
   110 
   111 /* BEGIN: Non Windows Definitions */
   112 #ifndef WINDOWSNT
   113 
   114 /* Structure forward declarations.  */
   115 
   116 struct sound;
   117 struct sound_device;
   118 
   119 /* The file header of RIFF-WAVE files (*.wav).  Files are always in
   120    little-endian byte-order.  */
   121 
   122 struct wav_header
   123 {
   124   u_int32_t magic;
   125   u_int32_t length;
   126   u_int32_t chunk_type;
   127   u_int32_t chunk_format;
   128   u_int32_t chunk_length;
   129   u_int16_t format;
   130   u_int16_t channels;
   131   u_int32_t sample_rate;
   132   u_int32_t bytes_per_second;
   133   u_int16_t sample_size;
   134   u_int16_t precision;
   135   u_int32_t chunk_data;
   136   u_int32_t data_length;
   137 };
   138 
   139 /* The file header of Sun adio files (*.au).  Files are always in
   140    big-endian byte-order.  */
   141 
   142 struct au_header
   143 {
   144   /* ASCII ".snd" */
   145   u_int32_t magic_number;
   146 
   147   /* Offset of data part from start of file. Minimum value is 24.  */
   148   u_int32_t data_offset;
   149 
   150   /* Size of data part, 0xffffffff if unknown.  */
   151   u_int32_t data_size;
   152 
   153   /* Data encoding format.
   154      1  8-bit ISDN u-law
   155      2  8-bit linear PCM (REF-PCM)
   156      3  16-bit linear PCM
   157      4  24-bit linear PCM
   158      5  32-bit linear PCM
   159      6  32-bit IEEE floating-point
   160      7  64-bit IEEE floating-point
   161      23 8-bit u-law compressed using CCITT 0.721 ADPCM voice data
   162      encoding scheme.  */
   163   u_int32_t encoding;
   164 
   165   /* Number of samples per second.  */
   166   u_int32_t sample_rate;
   167 
   168   /* Number of interleaved channels.  */
   169   u_int32_t channels;
   170 };
   171 
   172 /* Maximum of all sound file headers sizes.  */
   173 
   174 #define MAX_SOUND_HEADER_BYTES \
   175      max (sizeof (struct wav_header), sizeof (struct au_header))
   176 
   177 /* Interface structure for sound devices.  */
   178 
   179 struct sound_device
   180 {
   181   /* If a string, the name of the device; otherwise use a default.  */
   182   Lisp_Object file;
   183 
   184   /* File descriptor of the device.  */
   185   int fd;
   186 
   187   /* Device-dependent format.  */
   188   int format;
   189 
   190   /* Volume (0..100).  Zero means unspecified.  */
   191   int volume;
   192 
   193   /* Sample size.  */
   194   int sample_size;
   195 
   196   /* Sample rate.  */
   197   int sample_rate;
   198 
   199   /* Bytes per second.  */
   200   int bps;
   201 
   202   /* 1 = mono, 2 = stereo, 0 = don't set.  */
   203   int channels;
   204 
   205   /* Open device SD.  */
   206   void (* open) (struct sound_device *sd);
   207 
   208   /* Close device SD.  */
   209   void (* close) (struct sound_device *sd);
   210 
   211   /* Configure SD according to device-dependent parameters.  */
   212   void (* configure) (struct sound_device *device);
   213 
   214   /* Choose a device-dependent format for outputting sound S.  */
   215   void (* choose_format) (struct sound_device *sd,
   216                           struct sound *s);
   217 
   218   /* Return a preferred data size in bytes to be sent to write (below)
   219      each time.  2048 is used if this is NULL.  */
   220   ptrdiff_t (* period_size) (struct sound_device *sd);
   221 
   222   /* Write NYBTES bytes from BUFFER to device SD.  */
   223   void (* write) (struct sound_device *sd, const char *buffer,
   224                   ptrdiff_t nbytes);
   225 
   226   /* A place for devices to store additional data.  */
   227   void *data;
   228 };
   229 
   230 /* An enumerator for each supported sound file type.  */
   231 
   232 enum sound_type
   233 {
   234   RIFF,
   235   SUN_AUDIO
   236 };
   237 
   238 /* Interface structure for sound files.  */
   239 
   240 struct sound
   241 {
   242   /* The type of the file.  */
   243   enum sound_type type;
   244 
   245   /* File descriptor of a sound file.  */
   246   int fd;
   247 
   248   /* Pointer to sound file header.  This contains header_size bytes
   249      read from the start of a sound file.  */
   250   char *header;
   251 
   252   /* Number of bytes read from sound file.  This is always <=
   253      MAX_SOUND_HEADER_BYTES.  */
   254   int header_size;
   255 
   256   /* Sound data, if a string.  */
   257   Lisp_Object data;
   258 
   259   /* Play sound file S on device SD.  */
   260   void (* play) (struct sound *s, struct sound_device *sd);
   261 };
   262 
   263 /* These are set during `play-sound-internal' so that sound_cleanup has
   264    access to them.  */
   265 
   266 static struct sound_device *current_sound_device;
   267 static struct sound *current_sound;
   268 
   269 /* Function prototypes.  */
   270 
   271 static void vox_write (struct sound_device *, const char *, ptrdiff_t);
   272 static bool wav_init (struct sound *);
   273 static void wav_play (struct sound *, struct sound_device *);
   274 static bool au_init (struct sound *);
   275 static void au_play (struct sound *, struct sound_device *);
   276 
   277 /* END: Non Windows Definitions */
   278 #else /* WINDOWSNT */
   279 
   280 /* BEGIN: Windows Specific Definitions */
   281 static int do_play_sound (const char *, unsigned long);
   282 /*
   283   END: Windows Specific Definitions */
   284 #endif /* WINDOWSNT */
   285 
   286 
   287 /***********************************************************************
   288                                General
   289  ***********************************************************************/
   290 
   291 /* BEGIN: Common functions */
   292 
   293 #ifndef WINDOWSNT
   294 /* Like perror, but signals an error.  */
   295 
   296 static AVOID
   297 sound_perror (const char *msg)
   298 {
   299   int saved_errno = errno;
   300 
   301   turn_on_atimers (1);
   302 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   303   {
   304     sigset_t unblocked;
   305     sigemptyset (&unblocked);
   306 #ifdef USABLE_SIGIO
   307     sigaddset (&unblocked, SIGIO);
   308 #else
   309     sigaddset (&unblocked, SIGPOLL);
   310 #endif
   311     pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
   312   }
   313 #endif
   314   if (saved_errno != 0)
   315     error ("%s: %s", msg, emacs_strerror (saved_errno));
   316   else
   317     error ("%s", msg);
   318 }
   319 
   320 /* Display a warning message.  */
   321 
   322 static void
   323 sound_warning (const char *msg)
   324 {
   325   message1 (msg);
   326 }
   327 #endif  /* !WINDOWSNT */
   328 
   329 
   330 /* Parse sound specification SOUND, and fill ATTRS with what is
   331    found.  Value is non-zero if SOUND Is a valid sound specification.
   332    A valid sound specification is a list starting with the symbol
   333    `sound'.  The rest of the list is a property list which may
   334    contain the following key/value pairs:
   335 
   336    - `:file FILE'
   337 
   338    FILE is the sound file to play.  If it isn't an absolute name,
   339    it's searched under `data-directory'.
   340 
   341    - `:data DATA'
   342 
   343    DATA is a string containing sound data.  Either :file or :data
   344    may be present, but not both.
   345 
   346    - `:device DEVICE'
   347 
   348    DEVICE is the name of the device to play on, e.g. "/dev/dsp2".
   349    If not specified, a default device is used.
   350 
   351    - `:volume VOL'
   352 
   353    VOL must be an integer in the range [0, 100], or a float in the
   354    range [0, 1].  */
   355 
   356 static bool
   357 parse_sound (Lisp_Object sound, Lisp_Object *attrs)
   358 {
   359   /* SOUND must be a list starting with the symbol `sound'.  */
   360   if (!CONSP (sound) || !EQ (XCAR (sound), Qsound))
   361     return 0;
   362 
   363   sound = XCDR (sound);
   364   attrs[SOUND_FILE] = plist_get (sound, QCfile);
   365   attrs[SOUND_DATA] = plist_get (sound, QCdata);
   366   attrs[SOUND_DEVICE] = plist_get (sound, QCdevice);
   367   attrs[SOUND_VOLUME] = plist_get (sound, QCvolume);
   368 
   369 #ifndef WINDOWSNT
   370   /* File name or data must be specified.  */
   371   if (!STRINGP (attrs[SOUND_FILE])
   372       && !STRINGP (attrs[SOUND_DATA]))
   373     return 0;
   374 #else /* WINDOWSNT */
   375   /*
   376     Data is not supported in Windows.  Therefore a
   377     File name MUST be supplied.
   378   */
   379   if (!STRINGP (attrs[SOUND_FILE]))
   380     {
   381       return 0;
   382     }
   383 #endif /* WINDOWSNT */
   384 
   385   /* Volume must be in the range 0..100 or unspecified.  */
   386   if (!NILP (attrs[SOUND_VOLUME]))
   387     {
   388       if (FIXNUMP (attrs[SOUND_VOLUME]))
   389         {
   390           EMACS_INT volume = XFIXNUM (attrs[SOUND_VOLUME]);
   391           if (! (0 <= volume && volume <= 100))
   392             return 0;
   393         }
   394       else if (FLOATP (attrs[SOUND_VOLUME]))
   395         {
   396           double volume = XFLOAT_DATA (attrs[SOUND_VOLUME]);
   397           if (! (0 <= volume && volume <= 1))
   398             return 0;
   399         }
   400       else
   401         return 0;
   402     }
   403 
   404 #ifndef WINDOWSNT
   405   /* Device must be a string or unspecified.  */
   406   if (!NILP (attrs[SOUND_DEVICE])
   407       && !STRINGP (attrs[SOUND_DEVICE]))
   408     return 0;
   409 #endif  /* WINDOWSNT */
   410   /*
   411     Since device is ignored in Windows, it does not matter
   412     what it is.
   413    */
   414   return 1;
   415 }
   416 
   417 /* END: Common functions */
   418 
   419 /* BEGIN: Non Windows functions */
   420 #ifndef WINDOWSNT
   421 
   422 /* Return S's value as a string if S is a string, otherwise DEFAULT_VALUE.  */
   423 
   424 static char const *
   425 string_default (Lisp_Object s, char const *default_value)
   426 {
   427   return STRINGP (s) ? SSDATA (s) : default_value;
   428 }
   429 
   430 
   431 /* Find out the type of the sound file whose file descriptor is FD.
   432    S is the sound file structure to fill in.  */
   433 
   434 static void
   435 find_sound_type (struct sound *s)
   436 {
   437   if (!wav_init (s) && !au_init (s))
   438     error ("Unknown sound format");
   439 }
   440 
   441 
   442 /* Function installed by play-sound-internal with record_unwind_protect_void.  */
   443 
   444 static void
   445 sound_cleanup (void)
   446 {
   447   if (current_sound_device->close)
   448     current_sound_device->close (current_sound_device);
   449   if (current_sound->fd > 0)
   450     emacs_close (current_sound->fd);
   451   xfree (current_sound_device);
   452   xfree (current_sound);
   453 }
   454 
   455 /***********************************************************************
   456                         Byte-order Conversion
   457  ***********************************************************************/
   458 
   459 /* Convert 32-bit value VALUE which is in little-endian byte-order
   460    to host byte-order.  */
   461 
   462 static u_int32_t
   463 le2hl (u_int32_t value)
   464 {
   465 #ifdef WORDS_BIGENDIAN
   466   value = bswap_32 (value);
   467 #endif
   468   return value;
   469 }
   470 
   471 
   472 /* Convert 16-bit value VALUE which is in little-endian byte-order
   473    to host byte-order.  */
   474 
   475 static u_int16_t
   476 le2hs (u_int16_t value)
   477 {
   478 #ifdef WORDS_BIGENDIAN
   479   value = bswap_16 (value);
   480 #endif
   481   return value;
   482 }
   483 
   484 
   485 /* Convert 32-bit value VALUE which is in big-endian byte-order
   486    to host byte-order.  */
   487 
   488 static u_int32_t
   489 be2hl (u_int32_t value)
   490 {
   491 #ifndef WORDS_BIGENDIAN
   492   value = bswap_32 (value);
   493 #endif
   494   return value;
   495 }
   496 
   497 /***********************************************************************
   498                           RIFF-WAVE (*.wav)
   499  ***********************************************************************/
   500 
   501 /* Try to initialize sound file S from S->header.  S->header
   502    contains the first MAX_SOUND_HEADER_BYTES number of bytes from the
   503    sound file.  If the file is a WAV-format file, set up interface
   504    functions in S and convert header fields to host byte-order.
   505    Value is true if the file is a WAV file.  */
   506 
   507 static bool
   508 wav_init (struct sound *s)
   509 {
   510   struct wav_header *header = (struct wav_header *) s->header;
   511 
   512   if (s->header_size < sizeof *header
   513       || memcmp (s->header, "RIFF", 4) != 0)
   514     return 0;
   515 
   516   /* WAV files are in little-endian order.  Convert the header
   517      if on a big-endian machine.  */
   518   header->magic = le2hl (header->magic);
   519   header->length = le2hl (header->length);
   520   header->chunk_type = le2hl (header->chunk_type);
   521   header->chunk_format = le2hl (header->chunk_format);
   522   header->chunk_length = le2hl (header->chunk_length);
   523   header->format = le2hs (header->format);
   524   header->channels = le2hs (header->channels);
   525   header->sample_rate = le2hl (header->sample_rate);
   526   header->bytes_per_second = le2hl (header->bytes_per_second);
   527   header->sample_size = le2hs (header->sample_size);
   528   header->precision = le2hs (header->precision);
   529   header->chunk_data = le2hl (header->chunk_data);
   530   header->data_length = le2hl (header->data_length);
   531 
   532   /* Set up the interface functions for WAV.  */
   533   s->type = RIFF;
   534   s->play = wav_play;
   535 
   536   return 1;
   537 }
   538 
   539 
   540 /* Play RIFF-WAVE audio file S on sound device SD.  */
   541 
   542 static void
   543 wav_play (struct sound *s, struct sound_device *sd)
   544 {
   545   struct wav_header *header = (struct wav_header *) s->header;
   546 
   547   /* Let the device choose a suitable device-dependent format
   548      for the file.  */
   549   sd->choose_format (sd, s);
   550 
   551   /* Configure the device.  */
   552   sd->sample_size = header->sample_size;
   553   sd->sample_rate = header->sample_rate;
   554   sd->bps = header->bytes_per_second;
   555   sd->channels = header->channels;
   556   sd->configure (sd);
   557 
   558   /* Copy sound data to the device.  The WAV file specification is
   559      actually more complex.  This simple scheme worked with all WAV
   560      files I found so far.  If someone feels inclined to implement the
   561      whole RIFF-WAVE spec, please do.  */
   562   if (STRINGP (s->data))
   563     sd->write (sd, SSDATA (s->data) + sizeof *header,
   564                SBYTES (s->data) - sizeof *header);
   565   else
   566     {
   567       ptrdiff_t nbytes = 0;
   568       ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
   569       ptrdiff_t data_left = header->data_length;
   570       USE_SAFE_ALLOCA;
   571       char *buffer = SAFE_ALLOCA (blksize);
   572       lseek (s->fd, sizeof *header, SEEK_SET);
   573       while (data_left > 0
   574              && (nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
   575         {
   576           /* Don't play possible garbage at the end of file */
   577           if (data_left < nbytes) nbytes = data_left;
   578           data_left -= nbytes;
   579           sd->write (sd, buffer, nbytes);
   580         }
   581 
   582       if (nbytes < 0)
   583         sound_perror ("Error reading sound file");
   584       SAFE_FREE ();
   585     }
   586 }
   587 
   588 
   589 /***********************************************************************
   590                            Sun Audio (*.au)
   591  ***********************************************************************/
   592 
   593 /* Sun audio file encodings.  */
   594 
   595 enum au_encoding
   596 {
   597   AU_ENCODING_ULAW_8 = 1,
   598   AU_ENCODING_8,
   599   AU_ENCODING_16,
   600   AU_ENCODING_24,
   601   AU_ENCODING_32,
   602   AU_ENCODING_IEEE32,
   603   AU_ENCODING_IEEE64,
   604   AU_COMPRESSED = 23,
   605   AU_ENCODING_ALAW_8 = 27
   606 };
   607 
   608 
   609 /* Try to initialize sound file S from S->header.  S->header
   610    contains the first MAX_SOUND_HEADER_BYTES number of bytes from the
   611    sound file.  If the file is a AU-format file, set up interface
   612    functions in S and convert header fields to host byte-order.
   613    Value is true if the file is an AU file.  */
   614 
   615 static bool
   616 au_init (struct sound *s)
   617 {
   618   struct au_header *header = (struct au_header *) s->header;
   619 
   620   if (s->header_size < sizeof *header
   621       || memcmp (s->header, ".snd", 4) != 0)
   622     return 0;
   623 
   624   header->magic_number = be2hl (header->magic_number);
   625   header->data_offset = be2hl (header->data_offset);
   626   header->data_size = be2hl (header->data_size);
   627   header->encoding = be2hl (header->encoding);
   628   header->sample_rate = be2hl (header->sample_rate);
   629   header->channels = be2hl (header->channels);
   630 
   631   /* Set up the interface functions for AU.  */
   632   s->type = SUN_AUDIO;
   633   s->play = au_play;
   634 
   635   return 1;
   636 }
   637 
   638 
   639 /* Play Sun audio file S on sound device SD.  */
   640 
   641 static void
   642 au_play (struct sound *s, struct sound_device *sd)
   643 {
   644   struct au_header *header = (struct au_header *) s->header;
   645 
   646   sd->sample_size = 0;
   647   sd->sample_rate = header->sample_rate;
   648   sd->bps = 0;
   649   sd->channels = header->channels;
   650   sd->choose_format (sd, s);
   651   sd->configure (sd);
   652 
   653   if (STRINGP (s->data))
   654     sd->write (sd, SSDATA (s->data) + header->data_offset,
   655                SBYTES (s->data) - header->data_offset);
   656   else
   657     {
   658       ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
   659       ptrdiff_t nbytes;
   660 
   661       /* Seek */
   662       lseek (s->fd, header->data_offset, SEEK_SET);
   663 
   664       /* Copy sound data to the device.  */
   665       USE_SAFE_ALLOCA;
   666       char *buffer = SAFE_ALLOCA (blksize);
   667       while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
   668         sd->write (sd, buffer, nbytes);
   669 
   670       if (nbytes < 0)
   671         sound_perror ("Error reading sound file");
   672       SAFE_FREE ();
   673     }
   674 }
   675 
   676 
   677 /***********************************************************************
   678                        Voxware Driver Interface
   679  ***********************************************************************/
   680 
   681 /* This driver is available on GNU/Linux, and the free BSDs.  FreeBSD
   682    has a compatible own driver aka Luigi's driver.  */
   683 
   684 
   685 /* Open device SD.  If SD->file is a string, open that device,
   686    otherwise use a default device name.  */
   687 
   688 static void
   689 vox_open (struct sound_device *sd)
   690 {
   691   /* Open the sound device (eg /dev/dsp).  */
   692   char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE);
   693   sd->fd = emacs_open (file, O_WRONLY, 0);
   694   if (sd->fd < 0)
   695     sound_perror (file);
   696 }
   697 
   698 
   699 /* Configure device SD from parameters in it.  */
   700 
   701 static void
   702 vox_configure (struct sound_device *sd)
   703 {
   704   int val;
   705 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   706   sigset_t oldset, blocked;
   707 #endif
   708 
   709   eassert (sd->fd >= 0);
   710 
   711   /* On GNU/Linux, it seems that the device driver doesn't like to be
   712      interrupted by a signal.  Block the ones we know to cause
   713      troubles.  */
   714   turn_on_atimers (0);
   715 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   716   sigemptyset (&blocked);
   717 #ifdef USABLE_SIGIO
   718   sigaddset (&blocked, SIGIO);
   719 #else
   720   sigaddset (&blocked, SIGPOLL);
   721 #endif
   722   pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
   723 #endif
   724 
   725   val = sd->format;
   726   if (ioctl (sd->fd, SNDCTL_DSP_SETFMT, &sd->format) < 0
   727       || val != sd->format)
   728     sound_perror ("Could not set sound format");
   729 
   730   val = sd->channels != 1;
   731   if (ioctl (sd->fd, SNDCTL_DSP_STEREO, &val) < 0
   732       || val != (sd->channels != 1))
   733     sound_perror ("Could not set stereo/mono");
   734 
   735   /* I think bps and sampling_rate are the same, but who knows.
   736      Check this. and use SND_DSP_SPEED for both.  */
   737   if (sd->sample_rate > 0)
   738     {
   739       val = sd->sample_rate;
   740       if (ioctl (sd->fd, SNDCTL_DSP_SPEED, &sd->sample_rate) < 0)
   741         sound_perror ("Could not set sound speed");
   742       else if (val != sd->sample_rate)
   743         sound_warning ("Could not set sample rate");
   744     }
   745 
   746   if (sd->volume > 0)
   747     {
   748       int volume = sd->volume & 0xff;
   749       volume |= volume << 8;
   750       /* This may fail if there is no mixer.  Ignore the failure.  */
   751       ioctl (sd->fd, SOUND_MIXER_WRITE_PCM, &volume);
   752     }
   753 
   754   turn_on_atimers (1);
   755 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   756   pthread_sigmask (SIG_SETMASK, &oldset, 0);
   757 #endif
   758 }
   759 
   760 
   761 /* Close device SD if it is open.  */
   762 
   763 static void
   764 vox_close (struct sound_device *sd)
   765 {
   766   if (sd->fd >= 0)
   767     {
   768       /* On GNU/Linux, it seems that the device driver doesn't like to
   769          be interrupted by a signal.  Block the ones we know to cause
   770          troubles.  */
   771 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   772       sigset_t blocked, oldset;
   773       sigemptyset (&blocked);
   774 #ifdef USABLE_SIGIO
   775       sigaddset (&blocked, SIGIO);
   776 #else
   777       sigaddset (&blocked, SIGPOLL);
   778 #endif
   779       pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
   780 #endif
   781       turn_on_atimers (0);
   782 
   783       /* Flush sound data, and reset the device.  */
   784       ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
   785 
   786       turn_on_atimers (1);
   787 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   788       pthread_sigmask (SIG_SETMASK, &oldset, 0);
   789 #endif
   790 
   791       /* Close the device.  */
   792       emacs_close (sd->fd);
   793       sd->fd = -1;
   794     }
   795 }
   796 
   797 
   798 /* Choose device-dependent format for device SD from sound file S.  */
   799 
   800 static void
   801 vox_choose_format (struct sound_device *sd, struct sound *s)
   802 {
   803   if (s->type == RIFF)
   804     {
   805       struct wav_header *h = (struct wav_header *) s->header;
   806       if (h->precision == 8)
   807         sd->format = AFMT_U8;
   808       else if (h->precision == 16)
   809         sd->format = AFMT_S16_LE;
   810       else
   811         error ("Unsupported WAV file format");
   812     }
   813   else if (s->type == SUN_AUDIO)
   814     {
   815       struct au_header *header = (struct au_header *) s->header;
   816       switch (header->encoding)
   817         {
   818         case AU_ENCODING_ULAW_8:
   819         case AU_ENCODING_IEEE32:
   820         case AU_ENCODING_IEEE64:
   821           sd->format = AFMT_MU_LAW;
   822           break;
   823 
   824         case AU_ENCODING_8:
   825         case AU_ENCODING_16:
   826         case AU_ENCODING_24:
   827         case AU_ENCODING_32:
   828           sd->format = AFMT_S16_LE;
   829           break;
   830 
   831         default:
   832           error ("Unsupported AU file format");
   833         }
   834     }
   835   else
   836     emacs_abort ();
   837 }
   838 
   839 
   840 /* Initialize device SD.  Set up the interface functions in the device
   841    structure.  */
   842 
   843 static bool
   844 vox_init (struct sound_device *sd)
   845 {
   846   /* Open the sound device (eg /dev/dsp).  */
   847   char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE);
   848   int fd = emacs_open (file, O_WRONLY, 0);
   849   if (fd >= 0)
   850     emacs_close (fd);
   851   else
   852     return 0;
   853 
   854   sd->fd = -1;
   855   sd->open = vox_open;
   856   sd->close = vox_close;
   857   sd->configure = vox_configure;
   858   sd->choose_format = vox_choose_format;
   859   sd->write = vox_write;
   860   sd->period_size = NULL;
   861 
   862   return 1;
   863 }
   864 
   865 /* Write NBYTES bytes from BUFFER to device SD.  */
   866 
   867 static void
   868 vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
   869 {
   870   if (emacs_write_sig (sd->fd, buffer, nbytes) != nbytes)
   871     sound_perror ("Error writing to sound device");
   872 }
   873 
   874 #ifdef HAVE_ALSA
   875 /***********************************************************************
   876                        ALSA Driver Interface
   877  ***********************************************************************/
   878 
   879 /* This driver is available on GNU/Linux. */
   880 
   881 #ifndef DEFAULT_ALSA_SOUND_DEVICE
   882 #define DEFAULT_ALSA_SOUND_DEVICE "default"
   883 #endif
   884 
   885 static AVOID
   886 alsa_sound_perror (const char *msg, int err)
   887 {
   888   error ("%s: %s", msg, snd_strerror (err));
   889 }
   890 
   891 struct alsa_params
   892 {
   893   snd_pcm_t *handle;
   894   snd_pcm_hw_params_t *hwparams;
   895   snd_pcm_sw_params_t *swparams;
   896   snd_pcm_uframes_t period_size;
   897 };
   898 
   899 /* Open device SD.  If SD->file is a string, open that device,
   900    otherwise use a default device name.  */
   901 
   902 static void
   903 alsa_open (struct sound_device *sd)
   904 {
   905   /* Open the sound device.  Default is "default".  */
   906   struct alsa_params *p = xmalloc (sizeof *p);
   907   char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE);
   908   int err;
   909 
   910   p->handle = NULL;
   911   p->hwparams = NULL;
   912   p->swparams = NULL;
   913 
   914   sd->fd = -1;
   915   sd->data = p;
   916 
   917 
   918   err = snd_pcm_open (&p->handle, file, SND_PCM_STREAM_PLAYBACK, 0);
   919   if (err < 0)
   920     alsa_sound_perror (file, err);
   921 }
   922 
   923 static ptrdiff_t
   924 alsa_period_size (struct sound_device *sd)
   925 {
   926   struct alsa_params *p = (struct alsa_params *) sd->data;
   927   int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
   928   return p->period_size * (fact > 0 ? fact : 1);
   929 }
   930 
   931 static void
   932 alsa_configure (struct sound_device *sd)
   933 {
   934   int val, err, dir;
   935   unsigned uval;
   936   struct alsa_params *p = (struct alsa_params *) sd->data;
   937   snd_pcm_uframes_t buffer_size;
   938 
   939   eassert (p->handle != 0);
   940 
   941   err = snd_pcm_hw_params_malloc (&p->hwparams);
   942   if (err < 0)
   943     alsa_sound_perror ("Could not allocate hardware parameter structure", err);
   944 
   945   err = snd_pcm_sw_params_malloc (&p->swparams);
   946   if (err < 0)
   947     alsa_sound_perror ("Could not allocate software parameter structure", err);
   948 
   949   err = snd_pcm_hw_params_any (p->handle, p->hwparams);
   950   if (err < 0)
   951     alsa_sound_perror ("Could not initialize hardware parameter structure", err);
   952 
   953   err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
   954                                       SND_PCM_ACCESS_RW_INTERLEAVED);
   955   if (err < 0)
   956     alsa_sound_perror ("Could not set access type", err);
   957 
   958   val = sd->format;
   959   err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val);
   960   if (err < 0)
   961     alsa_sound_perror ("Could not set sound format", err);
   962 
   963   uval = sd->sample_rate;
   964   err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &uval, 0);
   965   if (err < 0)
   966     alsa_sound_perror ("Could not set sample rate", err);
   967 
   968   val = sd->channels;
   969   err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val);
   970   if (err < 0)
   971     alsa_sound_perror ("Could not set channel count", err);
   972 
   973   err = snd_pcm_hw_params (p->handle, p->hwparams);
   974   if (err < 0)
   975     alsa_sound_perror ("Could not set parameters", err);
   976 
   977 
   978   err = snd_pcm_hw_params_get_period_size (p->hwparams, &p->period_size, &dir);
   979   if (err < 0)
   980     alsa_sound_perror ("Unable to get period size for playback", err);
   981 
   982   err = snd_pcm_hw_params_get_buffer_size (p->hwparams, &buffer_size);
   983   if (err < 0)
   984     alsa_sound_perror ("Unable to get buffer size for playback", err);
   985 
   986   err = snd_pcm_sw_params_current (p->handle, p->swparams);
   987   if (err < 0)
   988     alsa_sound_perror ("Unable to determine current swparams for playback",
   989                        err);
   990 
   991   /* Start the transfer when the buffer is almost full */
   992   err = snd_pcm_sw_params_set_start_threshold (p->handle, p->swparams,
   993                                                (buffer_size / p->period_size)
   994                                                * p->period_size);
   995   if (err < 0)
   996     alsa_sound_perror ("Unable to set start threshold mode for playback", err);
   997 
   998   /* Allow the transfer when at least period_size samples can be processed */
   999   err = snd_pcm_sw_params_set_avail_min (p->handle, p->swparams, p->period_size);
  1000   if (err < 0)
  1001     alsa_sound_perror ("Unable to set avail min for playback", err);
  1002 
  1003   err = snd_pcm_sw_params (p->handle, p->swparams);
  1004   if (err < 0)
  1005     alsa_sound_perror ("Unable to set sw params for playback\n", err);
  1006 
  1007   snd_pcm_hw_params_free (p->hwparams);
  1008   p->hwparams = NULL;
  1009   snd_pcm_sw_params_free (p->swparams);
  1010   p->swparams = NULL;
  1011 
  1012   err = snd_pcm_prepare (p->handle);
  1013   if (err < 0)
  1014     alsa_sound_perror ("Could not prepare audio interface for use", err);
  1015 
  1016   if (sd->volume > 0)
  1017     {
  1018       int chn;
  1019       snd_mixer_t *handle;
  1020       snd_mixer_elem_t *e;
  1021       if (snd_mixer_open (&handle, 0) >= 0)
  1022         {
  1023           char const *file = string_default (sd->file,
  1024                                              DEFAULT_ALSA_SOUND_DEVICE);
  1025           if (snd_mixer_attach (handle, file) >= 0
  1026               && snd_mixer_load (handle) >= 0
  1027               && snd_mixer_selem_register (handle, NULL, NULL) >= 0)
  1028             for (e = snd_mixer_first_elem (handle);
  1029                  e;
  1030                  e = snd_mixer_elem_next (e))
  1031               {
  1032                 if (snd_mixer_selem_has_playback_volume (e))
  1033                   {
  1034                     long pmin, pmax, vol;
  1035                     snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax);
  1036                     vol = pmin + (sd->volume * (pmax - pmin)) / 100;
  1037 
  1038                     for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++)
  1039                       snd_mixer_selem_set_playback_volume (e, chn, vol);
  1040                   }
  1041               }
  1042           snd_mixer_close (handle);
  1043         }
  1044     }
  1045 }
  1046 
  1047 
  1048 /* Close device SD if it is open.  */
  1049 
  1050 static void
  1051 alsa_close (struct sound_device *sd)
  1052 {
  1053   struct alsa_params *p = (struct alsa_params *) sd->data;
  1054   if (p)
  1055     {
  1056       if (p->hwparams)
  1057         snd_pcm_hw_params_free (p->hwparams);
  1058       if (p->swparams)
  1059         snd_pcm_sw_params_free (p->swparams);
  1060       if (p->handle)
  1061         {
  1062           snd_pcm_drain (p->handle);
  1063           snd_pcm_close (p->handle);
  1064         }
  1065       xfree (p);
  1066     }
  1067 }
  1068 
  1069 /* Choose device-dependent format for device SD from sound file S.  */
  1070 
  1071 static void
  1072 alsa_choose_format (struct sound_device *sd, struct sound *s)
  1073 {
  1074   if (s->type == RIFF)
  1075     {
  1076       struct wav_header *h = (struct wav_header *) s->header;
  1077       if (h->precision == 8)
  1078         sd->format = SND_PCM_FORMAT_U8;
  1079       else if (h->precision == 16)
  1080           sd->format = SND_PCM_FORMAT_S16_LE;
  1081       else
  1082         error ("Unsupported WAV file format");
  1083     }
  1084   else if (s->type == SUN_AUDIO)
  1085     {
  1086       struct au_header *header = (struct au_header *) s->header;
  1087       switch (header->encoding)
  1088         {
  1089         case AU_ENCODING_ULAW_8:
  1090           sd->format = SND_PCM_FORMAT_MU_LAW;
  1091           break;
  1092         case AU_ENCODING_ALAW_8:
  1093           sd->format = SND_PCM_FORMAT_A_LAW;
  1094           break;
  1095         case AU_ENCODING_IEEE32:
  1096           sd->format = SND_PCM_FORMAT_FLOAT_BE;
  1097           break;
  1098         case AU_ENCODING_IEEE64:
  1099           sd->format = SND_PCM_FORMAT_FLOAT64_BE;
  1100           break;
  1101         case AU_ENCODING_8:
  1102           sd->format = SND_PCM_FORMAT_S8;
  1103           break;
  1104         case AU_ENCODING_16:
  1105           sd->format = SND_PCM_FORMAT_S16_BE;
  1106           break;
  1107         case AU_ENCODING_24:
  1108           sd->format = SND_PCM_FORMAT_S24_BE;
  1109           break;
  1110         case AU_ENCODING_32:
  1111           sd->format = SND_PCM_FORMAT_S32_BE;
  1112           break;
  1113 
  1114         default:
  1115           error ("Unsupported AU file format");
  1116         }
  1117     }
  1118   else
  1119     emacs_abort ();
  1120 }
  1121 
  1122 
  1123 /* Write NBYTES bytes from BUFFER to device SD.  */
  1124 
  1125 static void
  1126 alsa_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
  1127 {
  1128   struct alsa_params *p = (struct alsa_params *) sd->data;
  1129 
  1130   /* The third parameter to snd_pcm_writei is frames, not bytes. */
  1131   int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
  1132   ptrdiff_t nwritten = 0;
  1133   int err;
  1134 
  1135   while (nwritten < nbytes)
  1136     {
  1137       snd_pcm_uframes_t frames = (nbytes - nwritten)/fact;
  1138       if (frames == 0) break;
  1139 
  1140       err = snd_pcm_writei (p->handle, buffer + nwritten, frames);
  1141       if (err < 0)
  1142         {
  1143           if (err == -EPIPE)
  1144             {   /* under-run */
  1145               err = snd_pcm_prepare (p->handle);
  1146               if (err < 0)
  1147                 alsa_sound_perror ("Can't recover from underrun, prepare failed",
  1148                                    err);
  1149             }
  1150 #ifdef ESTRPIPE
  1151           else if (err == -ESTRPIPE)
  1152             {
  1153               while ((err = snd_pcm_resume (p->handle)) == -EAGAIN)
  1154                 sleep (1);      /* wait until the suspend flag is released */
  1155               if (err < 0)
  1156                 {
  1157                   err = snd_pcm_prepare (p->handle);
  1158                   if (err < 0)
  1159                     alsa_sound_perror ("Can't recover from suspend, "
  1160                                        "prepare failed",
  1161                                        err);
  1162                 }
  1163             }
  1164 #endif
  1165           else
  1166             alsa_sound_perror ("Error writing to sound device", err);
  1167 
  1168         }
  1169       else
  1170         nwritten += err * fact;
  1171     }
  1172 }
  1173 
  1174 static void
  1175 snd_error_quiet (const char *file, int line, const char *function, int err,
  1176                  const char *fmt)
  1177 {
  1178 }
  1179 
  1180 /* Initialize device SD.  Set up the interface functions in the device
  1181    structure.  */
  1182 
  1183 static bool
  1184 alsa_init (struct sound_device *sd)
  1185 {
  1186   /* Open the sound device.  Default is "default".  */
  1187   char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE);
  1188   snd_pcm_t *handle;
  1189   int err;
  1190 
  1191   snd_lib_error_set_handler ((snd_lib_error_handler_t) snd_error_quiet);
  1192   err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0);
  1193   snd_lib_error_set_handler (NULL);
  1194   if (err < 0)
  1195       return 0;
  1196   snd_pcm_close (handle);
  1197 
  1198   sd->fd = -1;
  1199   sd->open = alsa_open;
  1200   sd->close = alsa_close;
  1201   sd->configure = alsa_configure;
  1202   sd->choose_format = alsa_choose_format;
  1203   sd->write = alsa_write;
  1204   sd->period_size = alsa_period_size;
  1205 
  1206   return 1;
  1207 }
  1208 
  1209 #endif /* HAVE_ALSA */
  1210 
  1211 
  1212 /* END: Non Windows functions */
  1213 #else /* WINDOWSNT */
  1214 
  1215 /* BEGIN: Windows specific functions */
  1216 
  1217 #define SOUND_WARNING(func, error, text)                \
  1218   do {                                                  \
  1219     char buf[1024];                                     \
  1220     char err_string[MAXERRORLENGTH];                    \
  1221     func (error, err_string, sizeof (err_string));      \
  1222     _snprintf (buf, sizeof (buf), "%s\nMCI Error: %s",  \
  1223                text, err_string);                       \
  1224     message_with_string ("%s", build_string (buf), 1);  \
  1225   } while (0)
  1226 
  1227 static int
  1228 do_play_sound (const char *psz_file, unsigned long ui_volume)
  1229 {
  1230   int i_result = 0;
  1231   MCIERROR mci_error = 0;
  1232   char sz_cmd_buf_a[520];
  1233   char sz_ret_buf_a[520];
  1234   MMRESULT mm_result = MMSYSERR_NOERROR;
  1235   unsigned long ui_volume_org = 0;
  1236   BOOL b_reset_volume = FALSE;
  1237   char warn_text[560];
  1238 
  1239   /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
  1240      need to encode the file in the ANSI codepage on Windows 9X even
  1241      if w32_unicode_filenames is non-zero.  */
  1242   if (w32_major_version <= 4 || !w32_unicode_filenames)
  1243     {
  1244       char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
  1245 
  1246       filename_to_ansi (psz_file, fname_a);
  1247       fname_to_use = fname_a;
  1248       /* If the file name is not encodable in ANSI, try its short 8+3
  1249          alias.  This will only work if w32_unicode_filenames is
  1250          non-zero.  */
  1251       if (_mbspbrk ((const unsigned char *)fname_a,
  1252                     (const unsigned char *)"?"))
  1253         {
  1254           if (w32_get_short_filename (psz_file, shortname, MAX_PATH))
  1255             fname_to_use = shortname;
  1256           else
  1257             mci_error = MCIERR_FILE_NOT_FOUND;
  1258         }
  1259 
  1260       if (!mci_error)
  1261         {
  1262           memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
  1263           memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
  1264           sprintf (sz_cmd_buf_a,
  1265                    "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
  1266                    fname_to_use);
  1267           mci_error = mciSendStringA (sz_cmd_buf_a,
  1268                                       sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
  1269         }
  1270     }
  1271   else
  1272     {
  1273       wchar_t sz_cmd_buf_w[520];
  1274       wchar_t sz_ret_buf_w[520];
  1275       wchar_t fname_w[MAX_PATH];
  1276 
  1277       filename_to_utf16 (psz_file, fname_w);
  1278       memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
  1279       memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
  1280       /* _swprintf is not available on Windows 9X, so we construct the
  1281          UTF-16 command string by hand.  */
  1282       wcscpy (sz_cmd_buf_w, L"open \"");
  1283       wcscat (sz_cmd_buf_w, fname_w);
  1284       wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
  1285       mci_error = mciSendStringW (sz_cmd_buf_w,
  1286                                   sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
  1287     }
  1288   if (mci_error != 0)
  1289     {
  1290       strcpy (warn_text,
  1291               "mciSendString: 'open' command failed to open sound file ");
  1292       strcat (warn_text, psz_file);
  1293       SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
  1294       i_result = (int) mci_error;
  1295       return i_result;
  1296     }
  1297   if ((ui_volume > 0) && (ui_volume != UINT_MAX))
  1298     {
  1299       mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org);
  1300       if (mm_result == MMSYSERR_NOERROR)
  1301         {
  1302           b_reset_volume = TRUE;
  1303           mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume);
  1304           if (mm_result != MMSYSERR_NOERROR)
  1305             {
  1306               SOUND_WARNING (waveOutGetErrorText, mm_result,
  1307                              "waveOutSetVolume: failed to set the volume level"
  1308                              " of the WAVE_MAPPER device.\n"
  1309                              "As a result, the user selected volume level will"
  1310                              " not be used.");
  1311             }
  1312         }
  1313       else
  1314         {
  1315           SOUND_WARNING (waveOutGetErrorText, mm_result,
  1316                          "waveOutGetVolume: failed to obtain the original"
  1317                          " volume level of the WAVE_MAPPER device.\n"
  1318                          "As a result, the user selected volume level will"
  1319                          " not be used.");
  1320         }
  1321     }
  1322   memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
  1323   memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
  1324   strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
  1325   mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
  1326                               NULL);
  1327   if (mci_error != 0)
  1328     {
  1329       strcpy (warn_text,
  1330               "mciSendString: 'play' command failed to play sound file ");
  1331       strcat (warn_text, psz_file);
  1332       SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
  1333       i_result = (int) mci_error;
  1334     }
  1335   memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
  1336   memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
  1337   strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
  1338   mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
  1339                               NULL);
  1340   if (b_reset_volume == TRUE)
  1341     {
  1342       mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org);
  1343       if (mm_result != MMSYSERR_NOERROR)
  1344         {
  1345           SOUND_WARNING (waveOutGetErrorText, mm_result,
  1346                          "waveOutSetVolume: failed to reset the original"
  1347                          " volume level of the WAVE_MAPPER device.");
  1348         }
  1349     }
  1350   return i_result;
  1351 }
  1352 
  1353 /* END: Windows specific functions */
  1354 
  1355 #endif /* WINDOWSNT */
  1356 
  1357 DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1, 0,
  1358        doc: /* Play sound SOUND.
  1359 
  1360 Internal use only, use `play-sound' instead.  */)
  1361   (Lisp_Object sound)
  1362 {
  1363   Lisp_Object attrs[SOUND_ATTR_SENTINEL];
  1364   specpdl_ref count = SPECPDL_INDEX ();
  1365 
  1366 #ifdef WINDOWSNT
  1367   unsigned long ui_volume_tmp = UINT_MAX;
  1368   unsigned long ui_volume = UINT_MAX;
  1369 #endif /* WINDOWSNT */
  1370 
  1371   /* Parse the sound specification.  Give up if it is invalid.  */
  1372   if (!parse_sound (sound, attrs))
  1373     error ("Invalid sound specification");
  1374 
  1375   Lisp_Object file = Qnil;
  1376 
  1377 #ifndef WINDOWSNT
  1378   current_sound_device = xzalloc (sizeof *current_sound_device);
  1379   current_sound = xzalloc (sizeof *current_sound);
  1380   record_unwind_protect_void (sound_cleanup);
  1381   char headerbuf[MAX_SOUND_HEADER_BYTES];
  1382   current_sound->header = headerbuf;
  1383 
  1384   if (STRINGP (attrs[SOUND_FILE]))
  1385     {
  1386       /* Open the sound file.  */
  1387       current_sound->fd =
  1388         openp (list1 (Vdata_directory), attrs[SOUND_FILE], Qnil, &file, Qnil,
  1389                false, false);
  1390       if (current_sound->fd < 0)
  1391         sound_perror ("Could not open sound file");
  1392 
  1393       /* Read the first bytes from the file.  */
  1394       current_sound->header_size
  1395         = emacs_read (current_sound->fd, current_sound->header,
  1396                       MAX_SOUND_HEADER_BYTES);
  1397       if (current_sound->header_size < 0)
  1398         sound_perror ("Invalid sound file header");
  1399     }
  1400   else
  1401     {
  1402       current_sound->data = attrs[SOUND_DATA];
  1403       current_sound->header_size = min (MAX_SOUND_HEADER_BYTES, SBYTES (current_sound->data));
  1404       memcpy (current_sound->header, SDATA (current_sound->data),
  1405               current_sound->header_size);
  1406     }
  1407 
  1408   /* Find out the type of sound.  Give up if we can't tell.  */
  1409   find_sound_type (current_sound);
  1410 
  1411   /* Set up a device.  */
  1412   current_sound_device->file = attrs[SOUND_DEVICE];
  1413 
  1414   if (FIXNUMP (attrs[SOUND_VOLUME]))
  1415     current_sound_device->volume = XFIXNAT (attrs[SOUND_VOLUME]);
  1416   else if (FLOATP (attrs[SOUND_VOLUME]))
  1417     current_sound_device->volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
  1418 
  1419   CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);
  1420 
  1421 #ifdef HAVE_ALSA
  1422   if (!alsa_init (current_sound_device))
  1423 #endif
  1424     if (!vox_init (current_sound_device))
  1425       error ("No usable sound device driver found");
  1426 
  1427   /* Open the device.  */
  1428   current_sound_device->open (current_sound_device);
  1429 
  1430   /* Play the sound.  */
  1431   current_sound->play (current_sound, current_sound_device);
  1432 
  1433 #else /* WINDOWSNT */
  1434 
  1435   file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
  1436   file = ENCODE_FILE (file);
  1437   if (FIXNUMP (attrs[SOUND_VOLUME]))
  1438     {
  1439       ui_volume_tmp = XFIXNAT (attrs[SOUND_VOLUME]);
  1440     }
  1441   else if (FLOATP (attrs[SOUND_VOLUME]))
  1442     {
  1443       ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
  1444     }
  1445 
  1446   CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);
  1447 
  1448   /*
  1449     Based on some experiments I have conducted, a value of 100 or less
  1450     for the sound volume is much too low.  You cannot even hear it.
  1451     A value of UINT_MAX indicates that you wish for the sound to played
  1452     at the maximum possible volume.  A value of UINT_MAX/2 plays the
  1453     sound at 50% maximum volume.  Therefore the value passed to do_play_sound
  1454     (and thus to waveOutSetVolume) must be some fraction of UINT_MAX.
  1455     The following code adjusts the user specified volume level appropriately.
  1456   */
  1457   if ((ui_volume_tmp > 0) && (ui_volume_tmp <= 100))
  1458     {
  1459       ui_volume = ui_volume_tmp * (UINT_MAX / 100);
  1460     }
  1461   (void)do_play_sound (SSDATA (file), ui_volume);
  1462 
  1463 #endif /* WINDOWSNT */
  1464 
  1465   return unbind_to (count, Qnil);
  1466 }
  1467 
  1468 /***********************************************************************
  1469                             Initialization
  1470  ***********************************************************************/
  1471 
  1472 void
  1473 syms_of_sound (void)
  1474 {
  1475   DEFSYM (QCdevice, ":device");
  1476   DEFSYM (QCvolume, ":volume");
  1477   DEFSYM (Qsound, "sound");
  1478   DEFSYM (Qplay_sound_functions, "play-sound-functions");
  1479 
  1480   defsubr (&Splay_sound_internal);
  1481 }
  1482 
  1483 #endif /* HAVE_SOUND */

/* [<][>][^][v][top][bottom][index][help] */