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