(scan_lists): Follow coding convention.
[bpt/emacs.git] / src / sound.c
index af23690..0b15399 100644 (file)
@@ -1,12 +1,12 @@
 /* sound.c -- sound support.
    Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004,
 /* 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
 
 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,
 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 <soundcard.h>
 #endif
 #ifdef HAVE_ALSA
 #include <soundcard.h>
 #endif
 #ifdef HAVE_ALSA
+#ifdef ALSA_SUBDIR_INCLUDE
+#include <alsa/asoundlib.h>
+#else
 #include <asoundlib.h>
 #include <asoundlib.h>
-#endif
+#endif /* ALSA_SUBDIR_INCLUDE */
+#endif /* HAVE_ALSA */
 
 /* END: Non Windows Includes */
 
 
 /* END: Non Windows Includes */
 
@@ -93,7 +97,6 @@ Boston, MA 02110-1301, USA.  */
 #endif /* WINDOWSNT */
 
 /* BEGIN: Common Definitions */
 #endif /* WINDOWSNT */
 
 /* BEGIN: Common Definitions */
-#define abs(X)    ((X) < 0 ? -(X) : (X))
 
 /* Symbols.  */
 
 
 /* Symbols.  */
 
@@ -617,12 +620,18 @@ wav_play (s, sd)
       char *buffer;
       int nbytes;
       int blksize = sd->period_size ? sd->period_size (sd) : 2048;
       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);
 
       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");
 
       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;
        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
 }
 
 static void
@@ -990,6 +1000,7 @@ alsa_configure (sd)
      struct sound_device *sd;
 {
   int val, err, dir;
      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;
 
   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);
 
   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);
 
     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);
   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)
   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;
   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);
   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;
   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;
                     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);
                   }
                     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_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);
           snd_pcm_close (p->handle);
         }
       free (p);
@@ -1204,9 +1215,10 @@ alsa_write (sd, buffer, nbytes)
 
   while (nwritten < 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)
       if (err < 0)
         {
           if (err == -EPIPE)
@@ -1229,9 +1241,9 @@ alsa_write (sd, buffer, nbytes)
                                        err);
                 }
             }
                                        err);
                 }
             }
-          else 
+          else
             alsa_sound_perror ("Error writing to sound device", err);
             alsa_sound_perror ("Error writing to sound device", err);
-          
+
         }
       else
         nwritten += err * fact;
         }
       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)
   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;
 
   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.
 
 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;
 {
      (sound)
      Lisp_Object sound;
 {