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