Function: play-sound-internal

play-sound-internal is a function defined in sound.c.

Signature

(play-sound-internal SOUND)

Documentation

Play sound SOUND.

Internal use only, use play-sound instead.

Source Code

// Defined in /usr/src/emacs/src/sound.c
{
  Lisp_Object attrs[SOUND_ATTR_SENTINEL];
  specpdl_ref count = SPECPDL_INDEX ();

#ifdef WINDOWSNT
  unsigned long ui_volume = 0;
#endif /* WINDOWSNT */

  /* Parse the sound specification.  Give up if it is invalid.  */
  if (!parse_sound (sound, attrs))
    error ("Invalid sound specification");

  Lisp_Object file = Qnil;

#ifndef WINDOWSNT
  current_sound_device = xzalloc (sizeof *current_sound_device);
  current_sound = xzalloc (sizeof *current_sound);
  record_unwind_protect_void (sound_cleanup);
  char headerbuf[MAX_SOUND_HEADER_BYTES];
  current_sound->header = headerbuf;

  if (STRINGP (attrs[SOUND_FILE]))
    {
      /* Open the sound file.  */
      current_sound->fd =
	openp (list1 (Vdata_directory), attrs[SOUND_FILE], Qnil, &file, Qnil,
	       false, false, NULL);
      if (current_sound->fd < 0)
	sound_perror ("Could not open sound file");

      /* Read the first bytes from the file.  */
      current_sound->header_size
	= emacs_read (current_sound->fd, current_sound->header,
		      MAX_SOUND_HEADER_BYTES);
      if (current_sound->header_size < 0)
	sound_perror ("Invalid sound file header");
    }
  else
    {
      current_sound->data = attrs[SOUND_DATA];
      current_sound->header_size = min (MAX_SOUND_HEADER_BYTES, SBYTES (current_sound->data));
      memcpy (current_sound->header, SDATA (current_sound->data),
	      current_sound->header_size);
    }

  /* Find out the type of sound.  Give up if we can't tell.  */
  find_sound_type (current_sound);

  /* Set up a device.  */
  current_sound_device->file = attrs[SOUND_DEVICE];

  if (FIXNUMP (attrs[SOUND_VOLUME]))
    current_sound_device->volume = XFIXNAT (attrs[SOUND_VOLUME]);
  else if (FLOATP (attrs[SOUND_VOLUME]))
    current_sound_device->volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;

  CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);

#ifdef HAVE_ALSA
  if (!alsa_init (current_sound_device))
#endif
    if (!vox_init (current_sound_device))
      error ("No usable sound device driver found");

  /* Open the device.  */
  current_sound_device->open (current_sound_device);

  /* Play the sound.  */
  current_sound->play (current_sound, current_sound_device);

#else /* WINDOWSNT */


  if (FIXNUMP (attrs[SOUND_VOLUME]))
    ui_volume = XFIXNAT (attrs[SOUND_VOLUME]);
  else if (FLOATP (attrs[SOUND_VOLUME]))
    ui_volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;

  if (ui_volume > 100)
    ui_volume = 100;

  /* For volume (32 bits), low order 16 bits are the value for left
     channel, and high order 16 bits for the right channel.  We use the
     specified volume on both channels.  */
  ui_volume = ui_volume * 0xFFFF / 100;
  ui_volume = (ui_volume << 16) + ui_volume;

  CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);

  if (STRINGP (attrs[SOUND_FILE]))
    {
      file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
      file = ENCODE_FILE (file);
      do_play_sound (SSDATA (file), ui_volume, false);
    }
  else
    do_play_sound (SDATA (attrs[SOUND_DATA]), ui_volume, true);

#endif /* WINDOWSNT */

  return unbind_to (count, Qnil);
}