X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/1088b9226e7dac7314dab52ef0696a5f540900cd..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/sound.c diff --git a/src/sound.c b/src/sound.c index d20fa5ee8e..ad51c73446 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1,6 +1,6 @@ /* sound.c -- sound support. -Copyright (C) 1998-1999, 2001-2012 Free Software Foundation, Inc. +Copyright (C) 1998-1999, 2001-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -44,11 +44,10 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include + #include "lisp.h" #include "dispextern.h" #include "atimer.h" -#include #include "syssignal.h" /* END: Common Includes */ @@ -56,6 +55,8 @@ along with GNU Emacs. If not, see . */ /* BEGIN: Non Windows Includes */ #ifndef WINDOWSNT +#include + #include /* FreeBSD has machine/soundcard.h. Voxware sound driver docs mention @@ -182,8 +183,8 @@ struct au_header struct sound_device { - /* The name of the device or null meaning use a default device name. */ - char *file; + /* If a string, the name of the device; otherwise use a default. */ + Lisp_Object file; /* File descriptor of the device. */ int fd; @@ -272,25 +273,12 @@ static struct sound *current_sound; /* Function prototypes. */ -static void vox_open (struct sound_device *); -static void vox_configure (struct sound_device *); -static void vox_close (struct sound_device *sd); -static void vox_choose_format (struct sound_device *, struct sound *); -static int vox_init (struct sound_device *); static void vox_write (struct sound_device *, const char *, ptrdiff_t); -static void find_sound_type (struct sound *); -static u_int32_t le2hl (u_int32_t); -static u_int16_t le2hs (u_int16_t); -static u_int32_t be2hl (u_int32_t); -static int wav_init (struct sound *); +static bool wav_init (struct sound *); static void wav_play (struct sound *, struct sound_device *); -static int au_init (struct sound *); +static bool au_init (struct sound *); static void au_play (struct sound *, struct sound_device *); -#if 0 /* Currently not used. */ -static u_int16_t be2hs (u_int16_t); -#endif - /* END: Non Windows Definitions */ #else /* WINDOWSNT */ @@ -315,8 +303,13 @@ sound_perror (const char *msg) int saved_errno = errno; turn_on_atimers (1); -#ifdef SIGIO - sigunblock (sigmask (SIGIO)); +#ifdef USABLE_SIGIO + { + sigset_t unblocked; + sigemptyset (&unblocked); + sigaddset (&unblocked, SIGIO); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); + } #endif if (saved_errno != 0) error ("%s: %s", msg, strerror (saved_errno)); @@ -330,7 +323,7 @@ sound_perror (const char *msg) static void sound_warning (const char *msg) { - message ("%s", msg); + message1 (msg); } @@ -360,7 +353,7 @@ sound_warning (const char *msg) VOL must be an integer in the range [0, 100], or a float in the range [0, 1]. */ -static int +static bool parse_sound (Lisp_Object sound, Lisp_Object *attrs) { /* SOUND must be a list starting with the symbol `sound'. */ @@ -426,6 +419,15 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs) /* BEGIN: Non Windows functions */ #ifndef WINDOWSNT +/* Return S's value as a string if S is a string, otherwise DEFAULT_VALUE. */ + +static char const * +string_default (Lisp_Object s, char const *default_value) +{ + return STRINGP (s) ? SSDATA (s) : default_value; +} + + /* Find out the type of the sound file whose file descriptor is FD. S is the sound file structure to fill in. */ @@ -437,10 +439,10 @@ find_sound_type (struct sound *s) } -/* Function installed by play-sound-internal with record_unwind_protect. */ +/* Function installed by play-sound-internal with record_unwind_protect_void. */ -static Lisp_Object -sound_cleanup (Lisp_Object arg) +static void +sound_cleanup (void) { if (current_sound_device->close) current_sound_device->close (current_sound_device); @@ -448,8 +450,6 @@ sound_cleanup (Lisp_Object arg) emacs_close (current_sound->fd); xfree (current_sound_device); xfree (current_sound); - - return Qnil; } /*********************************************************************** @@ -463,8 +463,7 @@ static u_int32_t le2hl (u_int32_t value) { #ifdef WORDS_BIGENDIAN - unsigned char *p = (unsigned char *) &value; - value = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); + value = bswap_32 (value); #endif return value; } @@ -477,8 +476,7 @@ static u_int16_t le2hs (u_int16_t value) { #ifdef WORDS_BIGENDIAN - unsigned char *p = (unsigned char *) &value; - value = p[0] + (p[1] << 8); + value = bswap_16 (value); #endif return value; } @@ -491,30 +489,11 @@ static u_int32_t be2hl (u_int32_t value) { #ifndef WORDS_BIGENDIAN - unsigned char *p = (unsigned char *) &value; - value = p[3] + (p[2] << 8) + (p[1] << 16) + (p[0] << 24); -#endif - return value; -} - - -#if 0 /* Currently not used. */ - -/* Convert 16-bit value VALUE which is in big-endian byte-order - to host byte-order. */ - -static u_int16_t -be2hs (u_int16_t value) -{ -#ifndef WORDS_BIGENDIAN - unsigned char *p = (unsigned char *) &value; - value = p[1] + (p[0] << 8); + value = bswap_32 (value); #endif return value; } -#endif /* 0 */ - /*********************************************************************** RIFF-WAVE (*.wav) ***********************************************************************/ @@ -523,9 +502,9 @@ be2hs (u_int16_t value) contains the first MAX_SOUND_HEADER_BYTES number of bytes from the sound file. If the file is a WAV-format file, set up interface functions in S and convert header fields to host byte-order. - Value is non-zero if the file is a WAV file. */ + Value is true if the file is a WAV file. */ -static int +static bool wav_init (struct sound *s) { struct wav_header *header = (struct wav_header *) s->header; @@ -631,9 +610,9 @@ enum au_encoding contains the first MAX_SOUND_HEADER_BYTES number of bytes from the sound file. If the file is a AU-format file, set up interface functions in S and convert header fields to host byte-order. - Value is non-zero if the file is an AU file. */ + Value is true if the file is an AU file. */ -static int +static bool au_init (struct sound *s) { struct au_header *header = (struct au_header *) s->header; @@ -702,20 +681,14 @@ au_play (struct sound *s, struct sound_device *sd) has a compatible own driver aka Luigi's driver. */ -/* Open device SD. If SD->file is non-null, open that device, +/* Open device SD. If SD->file is a string, open that device, otherwise use a default device name. */ static void vox_open (struct sound_device *sd) { - const char *file; - /* Open the sound device (eg /dev/dsp). */ - if (sd->file) - file = sd->file; - else - file = DEFAULT_SOUND_DEVICE; - + char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE); sd->fd = emacs_open (file, O_WRONLY, 0); if (sd->fd < 0) sound_perror (file); @@ -728,6 +701,9 @@ static void vox_configure (struct sound_device *sd) { int val; +#ifdef USABLE_SIGIO + sigset_t oldset, blocked; +#endif eassert (sd->fd >= 0); @@ -735,8 +711,10 @@ vox_configure (struct sound_device *sd) interrupted by a signal. Block the ones we know to cause troubles. */ turn_on_atimers (0); -#ifdef SIGIO - sigblock (sigmask (SIGIO)); +#ifdef USABLE_SIGIO + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, &oldset); #endif val = sd->format; @@ -769,8 +747,8 @@ vox_configure (struct sound_device *sd) } turn_on_atimers (1); -#ifdef SIGIO - sigunblock (sigmask (SIGIO)); +#ifdef USABLE_SIGIO + pthread_sigmask (SIG_SETMASK, &oldset, 0); #endif } @@ -785,8 +763,11 @@ vox_close (struct sound_device *sd) /* On GNU/Linux, it seems that the device driver doesn't like to be interrupted by a signal. Block the ones we know to cause troubles. */ -#ifdef SIGIO - sigblock (sigmask (SIGIO)); +#ifdef USABLE_SIGIO + sigset_t blocked, oldset; + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, &oldset); #endif turn_on_atimers (0); @@ -794,8 +775,8 @@ vox_close (struct sound_device *sd) ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL); turn_on_atimers (1); -#ifdef SIGIO - sigunblock (sigmask (SIGIO)); +#ifdef USABLE_SIGIO + pthread_sigmask (SIG_SETMASK, &oldset, 0); #endif /* Close the device. */ @@ -850,18 +831,12 @@ vox_choose_format (struct sound_device *sd, struct sound *s) /* Initialize device SD. Set up the interface functions in the device structure. */ -static int +static bool vox_init (struct sound_device *sd) { - const char *file; - int fd; - /* Open the sound device (eg /dev/dsp). */ - if (sd->file) - file = sd->file; - else - file = DEFAULT_SOUND_DEVICE; - fd = emacs_open (file, O_WRONLY, 0); + char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE); + int fd = emacs_open (file, O_WRONLY, 0); if (fd >= 0) emacs_close (fd); else @@ -883,7 +858,7 @@ vox_init (struct sound_device *sd) static void vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes) { - if (emacs_write (sd->fd, buffer, nbytes) != nbytes) + if (emacs_write_sig (sd->fd, buffer, nbytes) != nbytes) sound_perror ("Error writing to sound device"); } @@ -912,23 +887,17 @@ struct alsa_params snd_pcm_uframes_t period_size; }; -/* Open device SD. If SD->file is non-null, open that device, +/* Open device SD. If SD->file is a string, open that device, otherwise use a default device name. */ static void alsa_open (struct sound_device *sd) { - const char *file; - struct alsa_params *p; - int err; - /* Open the sound device. Default is "default". */ - if (sd->file) - file = sd->file; - else - file = DEFAULT_ALSA_SOUND_DEVICE; + struct alsa_params *p = xmalloc (sizeof *p); + char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE); + int err; - p = xmalloc (sizeof *p); p->handle = NULL; p->hwparams = NULL; p->swparams = NULL; @@ -1040,10 +1009,10 @@ alsa_configure (struct sound_device *sd) int chn; snd_mixer_t *handle; snd_mixer_elem_t *e; - const char *file = sd->file ? sd->file : DEFAULT_ALSA_SOUND_DEVICE; - if (snd_mixer_open (&handle, 0) >= 0) { + char const *file = string_default (sd->file, + DEFAULT_ALSA_SOUND_DEVICE); if (snd_mixer_attach (handle, file) >= 0 && snd_mixer_load (handle) >= 0 && snd_mixer_selem_register (handle, NULL, NULL) >= 0) @@ -1200,19 +1169,14 @@ snd_error_quiet (const char *file, int line, const char *function, int err, /* Initialize device SD. Set up the interface functions in the device structure. */ -static int +static bool alsa_init (struct sound_device *sd) { - const char *file; + /* Open the sound device. Default is "default". */ + char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE); snd_pcm_t *handle; int err; - /* Open the sound device. Default is "default". */ - if (sd->file) - file = sd->file; - else - file = DEFAULT_ALSA_SOUND_DEVICE; - snd_lib_error_set_handler ((snd_lib_error_handler_t) snd_error_quiet); err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0); snd_lib_error_set_handler (NULL); @@ -1338,7 +1302,7 @@ Internal use only, use `play-sound' instead. */) (Lisp_Object sound) { Lisp_Object attrs[SOUND_ATTR_SENTINEL]; - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); #ifndef WINDOWSNT Lisp_Object file; @@ -1350,7 +1314,6 @@ Internal use only, use `play-sound' instead. */) char * psz_file = NULL; unsigned long ui_volume_tmp = UINT_MAX; unsigned long ui_volume = UINT_MAX; - int i_result = 0; #endif /* WINDOWSNT */ /* Parse the sound specification. Give up if it is invalid. */ @@ -1362,14 +1325,14 @@ Internal use only, use `play-sound' instead. */) GCPRO2 (sound, file); current_sound_device = xzalloc (sizeof *current_sound_device); current_sound = xzalloc (sizeof *current_sound); - record_unwind_protect (sound_cleanup, Qnil); + record_unwind_protect_void (sound_cleanup); current_sound->header = alloca (MAX_SOUND_HEADER_BYTES); if (STRINGP (attrs[SOUND_FILE])) { /* Open the sound file. */ - current_sound->fd = openp (Fcons (Vdata_directory, Qnil), - attrs[SOUND_FILE], Qnil, &file, Qnil); + current_sound->fd = openp (list1 (Vdata_directory), + attrs[SOUND_FILE], Qnil, &file, Qnil, false); if (current_sound->fd < 0) sound_perror ("Could not open sound file"); @@ -1392,12 +1355,7 @@ Internal use only, use `play-sound' instead. */) find_sound_type (current_sound); /* Set up a device. */ - if (STRINGP (attrs[SOUND_DEVICE])) - { - int len = SCHARS (attrs[SOUND_DEVICE]); - current_sound_device->file = alloca (len + 1); - strcpy (current_sound_device->file, SSDATA (attrs[SOUND_DEVICE])); - } + current_sound_device->file = attrs[SOUND_DEVICE]; if (INTEGERP (attrs[SOUND_VOLUME])) current_sound_device->volume = XFASTINT (attrs[SOUND_VOLUME]); @@ -1450,11 +1408,11 @@ Internal use only, use `play-sound' instead. */) { ui_volume = ui_volume_tmp * (UINT_MAX / 100); } - i_result = do_play_sound (psz_file, ui_volume); + do_play_sound (psz_file, ui_volume); #endif /* WINDOWSNT */ - unbind_to (count, Qnil); + dynwind_end (); return Qnil; } @@ -1465,12 +1423,12 @@ Internal use only, use `play-sound' instead. */) void syms_of_sound (void) { +#include "sound.x" + DEFSYM (QCdevice, ":device"); DEFSYM (QCvolume, ":volume"); DEFSYM (Qsound, "sound"); DEFSYM (Qplay_sound_functions, "play-sound-functions"); - - defsubr (&Splay_sound_internal); } #endif /* HAVE_SOUND */