X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/476e9367ec1f440aa23904b7bc482ea4a3b8041c..8b8bf8e68f19cdbe07521fa2d3c563265b27bd94:/src/sound.c diff --git a/src/sound.c b/src/sound.c index af2369040c..0b153991c1 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1,12 +1,12 @@ /* sound.c -- sound support. Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, - 2005, 2006 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -74,8 +74,12 @@ Boston, MA 02110-1301, USA. */ #include #endif #ifdef HAVE_ALSA +#ifdef ALSA_SUBDIR_INCLUDE +#include +#else #include -#endif +#endif /* ALSA_SUBDIR_INCLUDE */ +#endif /* HAVE_ALSA */ /* END: Non Windows Includes */ @@ -93,7 +97,6 @@ Boston, MA 02110-1301, USA. */ #endif /* WINDOWSNT */ /* BEGIN: Common Definitions */ -#define abs(X) ((X) < 0 ? -(X) : (X)) /* Symbols. */ @@ -617,12 +620,18 @@ wav_play (s, sd) char *buffer; int nbytes; int blksize = sd->period_size ? sd->period_size (sd) : 2048; + int data_left = header->data_length; buffer = (char *) alloca (blksize); lseek (s->fd, sizeof *header, SEEK_SET); - - while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0) - sd->write (sd, buffer, nbytes); + while (data_left > 0 + && (nbytes = emacs_read (s->fd, buffer, blksize)) > 0) + { + /* Don't play possible garbage at the end of file */ + if (data_left < nbytes) nbytes = data_left; + data_left -= nbytes; + sd->write (sd, buffer, nbytes); + } if (nbytes < 0) sound_perror ("Error reading sound file"); @@ -982,7 +991,8 @@ alsa_period_size (sd) struct sound_device *sd; { struct alsa_params *p = (struct alsa_params *) sd->data; - return p->period_size; + int fact = snd_pcm_format_size (sd->format, 1) * sd->channels; + return p->period_size * (fact > 0 ? fact : 1); } static void @@ -990,6 +1000,7 @@ alsa_configure (sd) struct sound_device *sd; { int val, err, dir; + unsigned uval; struct alsa_params *p = (struct alsa_params *) sd->data; snd_pcm_uframes_t buffer_size; @@ -1014,14 +1025,14 @@ alsa_configure (sd) val = sd->format; err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val); - if (err < 0) + if (err < 0) alsa_sound_perror ("Could not set sound format", err); - val = sd->sample_rate; - err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &val, 0); + uval = sd->sample_rate; + err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &uval, 0); if (err < 0) alsa_sound_perror ("Could not set sample rate", err); - + val = sd->channels; err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val); if (err < 0) @@ -1071,11 +1082,11 @@ alsa_configure (sd) p->hwparams = NULL; snd_pcm_sw_params_free (p->swparams); p->swparams = NULL; - + err = snd_pcm_prepare (p->handle); if (err < 0) alsa_sound_perror ("Could not prepare audio interface for use", err); - + if (sd->volume > 0) { int chn; @@ -1097,7 +1108,7 @@ alsa_configure (sd) long pmin, pmax; snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax); long vol = pmin + (sd->volume * (pmax - pmin)) / 100; - + for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) snd_mixer_selem_set_playback_volume (e, chn, vol); } @@ -1123,7 +1134,7 @@ alsa_close (sd) snd_pcm_sw_params_free (p->swparams); if (p->handle) { - snd_pcm_drain(p->handle); + snd_pcm_drain (p->handle); snd_pcm_close (p->handle); } free (p); @@ -1204,9 +1215,10 @@ alsa_write (sd, buffer, nbytes) while (nwritten < nbytes) { - err = snd_pcm_writei (p->handle, - buffer + nwritten, - (nbytes - nwritten)/fact); + snd_pcm_uframes_t frames = (nbytes - nwritten)/fact; + if (frames == 0) break; + + err = snd_pcm_writei (p->handle, buffer + nwritten, frames); if (err < 0) { if (err == -EPIPE) @@ -1229,9 +1241,9 @@ alsa_write (sd, buffer, nbytes) err); } } - else + else alsa_sound_perror ("Error writing to sound device", err); - + } else nwritten += err * fact; @@ -1269,7 +1281,8 @@ alsa_init (sd) err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0); snd_lib_error_set_handler (NULL); if (err < 0) - return 0; + return 0; + snd_pcm_close (handle); sd->fd = -1; sd->open = alsa_open; @@ -1372,7 +1385,7 @@ do_play_sound (psz_file, ui_volume) DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1, 0, doc: /* Play sound SOUND. -Internal use only, use `play-sound' instead.\n */) +Internal use only, use `play-sound' instead. */) (sound) Lisp_Object sound; {