all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
@ 2024-12-13 23:50 Cecilio Pardo
  2024-12-14  8:42 ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-13 23:50 UTC (permalink / raw)
  To: 74863

There are some problems with play-sound, but I didn't find an active bug 
for them. Before working on them I have a couple of questions:

- Is sound playing synchronous on purpose?

- To support :data, we can use the PlaySound function, but we will lose
the ability to play files other than wav. We can maintain the current 
code for files, and use PlaySound for :data. Another option would be to 
simply save data to a temp file and play the file.







^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-13 23:50 bug#74863: 31.0.50; Problems with play-sound on MS-Windows Cecilio Pardo
@ 2024-12-14  8:42 ` Eli Zaretskii
  2024-12-14 14:07   ` Cecilio Pardo
  2024-12-15 11:55   ` Cecilio Pardo
  0 siblings, 2 replies; 13+ messages in thread
From: Eli Zaretskii @ 2024-12-14  8:42 UTC (permalink / raw)
  To: Cecilio Pardo; +Cc: 74863

> Date: Sat, 14 Dec 2024 00:50:34 +0100
> From: Cecilio Pardo <cpardo@imayhem.com>
> 
> There are some problems with play-sound, but I didn't find an active bug 
> for them. Before working on them I have a couple of questions:
> 
> - Is sound playing synchronous on purpose?

It's synchronous because AFAIK the equivalent features on GNU/Linux
play sound synchronously.  We have a policy of not installing features
that might put non-free systems at an advantage.  So we can make the
sound playing on Windows asynchronous (which is very easily done on
Windows) once there is such a capability on free systems.

> - To support :data, we can use the PlaySound function, but we will lose
> the ability to play files other than wav. We can maintain the current 
> code for files, and use PlaySound for :data. Another option would be to 
> simply save data to a temp file and play the file.

I'd say the former is preferable, but without losing the ability to
play the files we can today.  That is, maintain the current code for
files and add new code for :data.

Thanks.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-14  8:42 ` Eli Zaretskii
@ 2024-12-14 14:07   ` Cecilio Pardo
  2024-12-14 14:56     ` Eli Zaretskii
  2024-12-15 11:55   ` Cecilio Pardo
  1 sibling, 1 reply; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-14 14:07 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 74863

On 14/12/2024 9:42, Eli Zaretskii wrote:
>> - Is sound playing synchronous on purpose?
> 
> It's synchronous because AFAIK the equivalent features on GNU/Linux
> play sound synchronously.  We have a policy of not installing features
> that might put non-free systems at an advantage.  So we can make the
> sound playing on Windows asynchronous (which is very easily done on
> Windows) once there is such a capability on free systems.

Should we add support for PipeWire on GNU/Linux?







^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-14 14:07   ` Cecilio Pardo
@ 2024-12-14 14:56     ` Eli Zaretskii
  2024-12-15  1:35       ` Stefan Kangas
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2024-12-14 14:56 UTC (permalink / raw)
  To: Cecilio Pardo; +Cc: 74863

> Date: Sat, 14 Dec 2024 15:07:39 +0100
> Cc: 74863@debbugs.gnu.org
> From: Cecilio Pardo <cpardo@imayhem.com>
> 
> On 14/12/2024 9:42, Eli Zaretskii wrote:
> >> - Is sound playing synchronous on purpose?
> > 
> > It's synchronous because AFAIK the equivalent features on GNU/Linux
> > play sound synchronously.  We have a policy of not installing features
> > that might put non-free systems at an advantage.  So we can make the
> > sound playing on Windows asynchronous (which is very easily done on
> > Windows) once there is such a capability on free systems.
> 
> Should we add support for PipeWire on GNU/Linux?

I don't know what PipeWire is, so I have no opinion on this.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-14 14:56     ` Eli Zaretskii
@ 2024-12-15  1:35       ` Stefan Kangas
  2024-12-15 20:36         ` Cecilio Pardo
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Kangas @ 2024-12-15  1:35 UTC (permalink / raw)
  To: Eli Zaretskii, Cecilio Pardo; +Cc: 74863

Eli Zaretskii <eliz@gnu.org> writes:

>> Should we add support for PipeWire on GNU/Linux?

ALSA clients can be configured to output via PipeWire, and the Pipewire
project itself recommends staying with the ALSA API, at least for now:

https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#what-audio-api-do-you-recommend-to-use

> I don't know what PipeWire is, so I have no opinion on this.

It's a new multimedia server that replaces both Pulse Audio and JACK.
AFAIK, it's the default sound server on Debian when using Gnome, and on
Fedora 34.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-14  8:42 ` Eli Zaretskii
  2024-12-14 14:07   ` Cecilio Pardo
@ 2024-12-15 11:55   ` Cecilio Pardo
  2024-12-15 12:50     ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-15 11:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 74863

[-- Attachment #1: Type: text/plain, Size: 1042 bytes --]

On 14/12/2024 9:42, Eli Zaretskii wrote:
>> - To support :data, we can use the PlaySound function, but we will lose
>> the ability to play files other than wav. We can maintain the current
>> code for files, and use PlaySound for :data. Another option would be to
>> simply save data to a temp file and play the file.
> 
> I'd say the former is preferable, but without losing the ability to
> play the files we can today.  That is, maintain the current code for
> files and add new code for :data.

This patch adds support for :data using PlaySound, keeping the current 
code for files.

It also fixes a problem in the handling of the volume. Let me know if I 
have to make a separate patch/bug.

Tested with mingw64 and mingw32.

To test:

(defun load-file-into-unibyte-string (file-path)
   (with-temp-buffer
     (set-buffer-multibyte nil)
     (insert-file-contents file-path)
     (buffer-string)))

(play-sound `(sound :data ,(load-file-into-unibyte-string "awav.wav") 
:volume 100))

(play-sound '(sound :file "awav.wav" :volume 100))

[-- Attachment #2: 0001-Add-support-for-the-data-keyword-for-play-sound-in-M.patch --]
[-- Type: text/plain, Size: 13423 bytes --]

From 27225d244bad747e7f2469afe6d8ad0d374e2910 Mon Sep 17 00:00:00 2001
From: Cecilio Pardo <cpardo@imayhem.com>
Date: Sun, 15 Dec 2024 01:13:16 +0100
Subject: [PATCH] Add support for the ':data' keyword for play-sound in
 MS-Windows.

Also fix an error on volume handling.

* etc/NEWS: Add entry for this change.
* etc/PROBLEMS: Remove entry about missing support for :data.
* src/sound.c (parse_sound): Check that either :file or :data is
present.
(do_play_sound): Added parameter to select file or data, and code to
play from data.
(Fplay_sound_internal): Fixed volume format, and send file or data to
do_play_sound.
---
 etc/NEWS     |   5 ++
 etc/PROBLEMS |   5 --
 src/sound.c  | 232 +++++++++++++++++++++++++--------------------------
 3 files changed, 117 insertions(+), 125 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 48546a2d916..b07d75a665a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1061,6 +1061,11 @@ current buffer, if the major mode supports it.  (Support for
 Transformed images are smoothed using the bilinear interpolation by
 means of the GDI+ library.
 
+---
+** Emacs on MS-Windows now supports the ':data' keyword for 'play-sound'.
+In addition to ':file FILE' for playing a sound from a file, ':data
+DATA' can now be used to play a sound from memory.
+
 \f
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 8de12a78613..c1745e8d18f 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -3278,11 +3278,6 @@ Files larger than 4GB cause overflow in the size (represented as a
 well, since the Windows port uses a Lisp emulation of 'ls', which relies
 on 'file-attributes'.
 
-** Playing sound doesn't support the :data method
-
-Sound playing is not supported with the ':data DATA' key-value pair.
-You _must_ use the ':file FILE' method.
-
 ** Typing Alt-Shift has strange effects on MS-Windows.
 
 This combination of keys is a command to change keyboard layout.  If
diff --git a/src/sound.c b/src/sound.c
index 004015fc936..2cc0e71f998 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -26,14 +26,12 @@ Copyright (C) 1998-1999, 2001-2024 Free Software Foundation, Inc.
   implementation of the play-sound specification for Windows.
 
   Notes:
-  In the Windows implementation of play-sound-internal only the
-  :file and :volume keywords are supported.  The :device keyword,
-  if present, is ignored.  The :data keyword, if present, will
-  cause an error to be generated.
+  In the Windows implementation of play-sound-internal the :device
+  keyword, if present, is ignored.
 
   The Windows implementation of play-sound is implemented via the
-  Windows API functions mciSendString, waveOutGetVolume, and
-  waveOutSetVolume which are exported by Winmm.dll.
+  Windows API functions mciSendString, waveOutGetVolume,
+  waveOutSetVolume and PlaySound which are exported by Winmm.dll.
 */
 
 #include <config.h>
@@ -278,7 +276,7 @@ #define MAX_SOUND_HEADER_BYTES \
 #else /* WINDOWSNT */
 
 /* BEGIN: Windows Specific Definitions */
-static int do_play_sound (const char *, unsigned long);
+static int do_play_sound (const char *, unsigned long, bool);
 /*
   END: Windows Specific Definitions */
 #endif /* WINDOWSNT */
@@ -366,21 +364,10 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs)
   attrs[SOUND_DEVICE] = plist_get (sound, QCdevice);
   attrs[SOUND_VOLUME] = plist_get (sound, QCvolume);
 
-#ifndef WINDOWSNT
   /* File name or data must be specified.  */
   if (!STRINGP (attrs[SOUND_FILE])
       && !STRINGP (attrs[SOUND_DATA]))
     return 0;
-#else /* WINDOWSNT */
-  /*
-    Data is not supported in Windows.  Therefore a
-    File name MUST be supplied.
-  */
-  if (!STRINGP (attrs[SOUND_FILE]))
-    {
-      return 0;
-    }
-#endif /* WINDOWSNT */
 
   /* Volume must be in the range 0..100 or unspecified.  */
   if (!NILP (attrs[SOUND_VOLUME]))
@@ -1225,7 +1212,7 @@ #define SOUND_WARNING(func, error, text)		\
   } while (0)
 
 static int
-do_play_sound (const char *psz_file, unsigned long ui_volume)
+do_play_sound (const char *psz_file_or_data, unsigned long ui_volume, bool in_memory)
 {
   int i_result = 0;
   MCIERROR mci_error = 0;
@@ -1236,65 +1223,7 @@ do_play_sound (const char *psz_file, unsigned long ui_volume)
   BOOL b_reset_volume = FALSE;
   char warn_text[560];
 
-  /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
-     need to encode the file in the ANSI codepage on Windows 9X even
-     if w32_unicode_filenames is non-zero.  */
-  if (w32_major_version <= 4 || !w32_unicode_filenames)
-    {
-      char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
-
-      filename_to_ansi (psz_file, fname_a);
-      fname_to_use = fname_a;
-      /* If the file name is not encodable in ANSI, try its short 8+3
-	 alias.  This will only work if w32_unicode_filenames is
-	 non-zero.  */
-      if (_mbspbrk ((const unsigned char *)fname_a,
-		    (const unsigned char *)"?"))
-	{
-	  if (w32_get_short_filename (psz_file, shortname, MAX_PATH))
-	    fname_to_use = shortname;
-	  else
-	    mci_error = MCIERR_FILE_NOT_FOUND;
-	}
-
-      if (!mci_error)
-	{
-	  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-	  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-	  sprintf (sz_cmd_buf_a,
-		   "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
-		   fname_to_use);
-	  mci_error = mciSendStringA (sz_cmd_buf_a,
-				      sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
-	}
-    }
-  else
-    {
-      wchar_t sz_cmd_buf_w[520];
-      wchar_t sz_ret_buf_w[520];
-      wchar_t fname_w[MAX_PATH];
-
-      filename_to_utf16 (psz_file, fname_w);
-      memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
-      memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
-      /* _swprintf is not available on Windows 9X, so we construct the
-	 UTF-16 command string by hand.  */
-      wcscpy (sz_cmd_buf_w, L"open \"");
-      wcscat (sz_cmd_buf_w, fname_w);
-      wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
-      mci_error = mciSendStringW (sz_cmd_buf_w,
-				  sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
-    }
-  if (mci_error != 0)
-    {
-      strcpy (warn_text,
-	      "mciSendString: 'open' command failed to open sound file ");
-      strcat (warn_text, psz_file);
-      SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
-      i_result = (int) mci_error;
-      return i_result;
-    }
-  if ((ui_volume > 0) && (ui_volume != UINT_MAX))
+  if (ui_volume > 0)
     {
       mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org);
       if (mm_result == MMSYSERR_NOERROR)
@@ -1319,34 +1248,100 @@ do_play_sound (const char *psz_file, unsigned long ui_volume)
                          " not be used.");
         }
     }
-  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-  strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
-  mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
-			      NULL);
-  if (mci_error != 0)
+
+  if (in_memory)
+    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);
+  else
     {
-      strcpy (warn_text,
-	      "mciSendString: 'play' command failed to play sound file ");
-      strcat (warn_text, psz_file);
-      SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
-      i_result = (int) mci_error;
+      /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
+	 need to encode the file in the ANSI codepage on Windows 9X even
+	 if w32_unicode_filenames is non-zero.  */
+      if (w32_major_version <= 4 || !w32_unicode_filenames)
+	{
+	  char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
+
+	  filename_to_ansi (psz_file_or_data, fname_a);
+	  fname_to_use = fname_a;
+	  /* If the file name is not encodable in ANSI, try its short 8+3
+	     alias.  This will only work if w32_unicode_filenames is
+	     non-zero.  */
+	  if (_mbspbrk ((const unsigned char *)fname_a,
+			(const unsigned char *)"?"))
+	    {
+	      if (w32_get_short_filename (psz_file_or_data, shortname, MAX_PATH))
+		fname_to_use = shortname;
+	      else
+		mci_error = MCIERR_FILE_NOT_FOUND;
+	    }
+
+	  if (!mci_error)
+	    {
+	      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+	      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+	      sprintf (sz_cmd_buf_a,
+		       "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
+		       fname_to_use);
+	      mci_error = mciSendStringA (sz_cmd_buf_a,
+					  sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
+	    }
+	}
+      else
+	{
+	  wchar_t sz_cmd_buf_w[520];
+	  wchar_t sz_ret_buf_w[520];
+	  wchar_t fname_w[MAX_PATH];
+
+	  filename_to_utf16 (psz_file_or_data, fname_w);
+	  memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
+	  memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
+	  /* _swprintf is not available on Windows 9X, so we construct the
+	     UTF-16 command string by hand.  */
+	  wcscpy (sz_cmd_buf_w, L"open \"");
+	  wcscat (sz_cmd_buf_w, fname_w);
+	  wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
+	  mci_error = mciSendStringW (sz_cmd_buf_w,
+				      sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
+	}
+      if (mci_error != 0)
+	{
+	  strcpy (warn_text,
+		  "mciSendString: 'open' command failed to open sound file ");
+	  strcat (warn_text, psz_file_or_data);
+	  SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
+	  i_result = (int) mci_error;
+	  return i_result;
+	}
+      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+      strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
+      mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
+				  NULL);
+      if (mci_error != 0)
+	{
+	  strcpy (warn_text,
+		  "mciSendString: 'play' command failed to play sound file ");
+	  strcat (warn_text, psz_file_or_data);
+	  SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
+	  i_result = (int) mci_error;
+	}
+      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+      strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
+      mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
+				  NULL);
     }
-  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-  strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
-  mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
-			      NULL);
+
   if (b_reset_volume == TRUE)
     {
       mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org);
       if (mm_result != MMSYSERR_NOERROR)
-        {
-          SOUND_WARNING (waveOutGetErrorText, mm_result,
+	{
+	  SOUND_WARNING (waveOutGetErrorText, mm_result,
 			 "waveOutSetVolume: failed to reset the original"
-                         " volume level of the WAVE_MAPPER device.");
-        }
+			 " volume level of the WAVE_MAPPER device.");
+	}
     }
+
   return i_result;
 }
 
@@ -1364,8 +1359,7 @@ DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1,
   specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
-  unsigned long ui_volume_tmp = UINT_MAX;
-  unsigned long ui_volume = UINT_MAX;
+  unsigned long ui_volume = 0;
 #endif /* WINDOWSNT */
 
   /* Parse the sound specification.  Give up if it is invalid.  */
@@ -1432,33 +1426,31 @@ DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1,
 
 #else /* WINDOWSNT */
 
-  file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
-  file = ENCODE_FILE (file);
+
   if (FIXNUMP (attrs[SOUND_VOLUME]))
-    {
-      ui_volume_tmp = XFIXNAT (attrs[SOUND_VOLUME]);
-    }
+    ui_volume = XFIXNAT (attrs[SOUND_VOLUME]);
   else if (FLOATP (attrs[SOUND_VOLUME]))
-    {
-      ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
-    }
+    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);
 
-  /*
-    Based on some experiments I have conducted, a value of 100 or less
-    for the sound volume is much too low.  You cannot even hear it.
-    A value of UINT_MAX indicates that you wish for the sound to played
-    at the maximum possible volume.  A value of UINT_MAX/2 plays the
-    sound at 50% maximum volume.  Therefore the value passed to do_play_sound
-    (and thus to waveOutSetVolume) must be some fraction of UINT_MAX.
-    The following code adjusts the user specified volume level appropriately.
-  */
-  if ((ui_volume_tmp > 0) && (ui_volume_tmp <= 100))
+  if (STRINGP (attrs[SOUND_FILE]))
     {
-      ui_volume = ui_volume_tmp * (UINT_MAX / 100);
+      file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
+      file = ENCODE_FILE (file);
+      do_play_sound (SSDATA (file), ui_volume, false);
     }
-  (void)do_play_sound (SSDATA (file), ui_volume);
+  else
+    do_play_sound (SDATA (attrs[SOUND_DATA]), ui_volume, true);
 
 #endif /* WINDOWSNT */
 
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 11:55   ` Cecilio Pardo
@ 2024-12-15 12:50     ` Eli Zaretskii
  2024-12-15 18:33       ` Cecilio Pardo
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2024-12-15 12:50 UTC (permalink / raw)
  To: Cecilio Pardo; +Cc: 74863

> Date: Sun, 15 Dec 2024 12:55:35 +0100
> Cc: 74863@debbugs.gnu.org
> From: Cecilio Pardo <cpardo@imayhem.com>
> 
> This patch adds support for :data using PlaySound, keeping the current 
> code for files.

Thanks.

> It also fixes a problem in the handling of the volume. Let me know if I 
> have to make a separate patch/bug.

No need.

> To test:
> 
> (defun load-file-into-unibyte-string (file-path)
>    (with-temp-buffer
>      (set-buffer-multibyte nil)
>      (insert-file-contents file-path)
>      (buffer-string)))
> 
> (play-sound `(sound :data ,(load-file-into-unibyte-string "awav.wav") 
> :volume 100))

What's wrong with insert-file-contents-literally?

> +  if (in_memory)
> +    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);

AFAIU, the documentation seems to say that the string passed as the
first argument to PlaySound is limited to 256 characters (i.e. bytes)?
If so, how do we play longer sounds?

Should we also use SND_SENTRY flag (on Vista and later)?





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 12:50     ` Eli Zaretskii
@ 2024-12-15 18:33       ` Cecilio Pardo
  2024-12-15 18:48         ` Eli Zaretskii
  2024-12-21 10:37         ` Eli Zaretskii
  0 siblings, 2 replies; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-15 18:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 74863

[-- Attachment #1: Type: text/plain, Size: 1163 bytes --]

On 15/12/2024 13:50, Eli Zaretskii wrote:

>> (defun load-file-into-unibyte-string (file-path)
>>     (with-temp-buffer
>>       (set-buffer-multibyte nil)
>>       (insert-file-contents file-path)
>>       (buffer-string)))
>>
>> (play-sound `(sound :data ,(load-file-into-unibyte-string "awav.wav")
>> :volume 100))
> 
> What's wrong with insert-file-contents-literally?

Nothing. So many functions...

> 
>> +  if (in_memory)
>> +    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);
> 
> AFAIU, the documentation seems to say that the string passed as the
> first argument to PlaySound is limited to 256 characters (i.e. bytes)?
> If so, how do we play longer sounds?

I think this limitation applies only when the argument points to a 
string, and not when using SND_MEMORY, which is documented with: "The 
pszSound parameter points to a sound loaded in memory."

It's true the documentation doesn't say so, and I haven't found any 
clarification by Microsoft, but SND_MEMORY would be useless otherwise. 
Also I see normal usage searching the internet.

> Should we also use SND_SENTRY flag (on Vista and later)?

Yes, done in the attached patch.


[-- Attachment #2: 0001-Add-support-for-the-data-keyword-for-play-sound-in-M.patch --]
[-- Type: text/plain, Size: 13836 bytes --]

From b749e748672dea5e429f168e531de33f499f2b93 Mon Sep 17 00:00:00 2001
From: Cecilio Pardo <cpardo@imayhem.com>
Date: Sun, 15 Dec 2024 01:13:16 +0100
Subject: [PATCH] Add support for the ':data' keyword for play-sound in
 MS-Windows.

Also fix an error on volume handling.

* etc/NEWS: Add entry for this change.
* etc/PROBLEMS: Remove entry about missing support for :data.
* src/sound.c (parse_sound): Check that either :file or :data is
present.
(do_play_sound): Added parameter to select file or data, and code to
play from data.
(Fplay_sound_internal): Fixed volume format, and send file or data to
do_play_sound.
---
 etc/NEWS     |   5 ++
 etc/PROBLEMS |   5 --
 src/sound.c  | 242 ++++++++++++++++++++++++++-------------------------
 3 files changed, 127 insertions(+), 125 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 48546a2d916..b07d75a665a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1061,6 +1061,11 @@ current buffer, if the major mode supports it.  (Support for
 Transformed images are smoothed using the bilinear interpolation by
 means of the GDI+ library.
 
+---
+** Emacs on MS-Windows now supports the ':data' keyword for 'play-sound'.
+In addition to ':file FILE' for playing a sound from a file, ':data
+DATA' can now be used to play a sound from memory.
+
 \f
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 8de12a78613..c1745e8d18f 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -3278,11 +3278,6 @@ Files larger than 4GB cause overflow in the size (represented as a
 well, since the Windows port uses a Lisp emulation of 'ls', which relies
 on 'file-attributes'.
 
-** Playing sound doesn't support the :data method
-
-Sound playing is not supported with the ':data DATA' key-value pair.
-You _must_ use the ':file FILE' method.
-
 ** Typing Alt-Shift has strange effects on MS-Windows.
 
 This combination of keys is a command to change keyboard layout.  If
diff --git a/src/sound.c b/src/sound.c
index 004015fc936..843d05d2349 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -26,14 +26,12 @@ Copyright (C) 1998-1999, 2001-2024 Free Software Foundation, Inc.
   implementation of the play-sound specification for Windows.
 
   Notes:
-  In the Windows implementation of play-sound-internal only the
-  :file and :volume keywords are supported.  The :device keyword,
-  if present, is ignored.  The :data keyword, if present, will
-  cause an error to be generated.
+  In the Windows implementation of play-sound-internal the :device
+  keyword, if present, is ignored.
 
   The Windows implementation of play-sound is implemented via the
-  Windows API functions mciSendString, waveOutGetVolume, and
-  waveOutSetVolume which are exported by Winmm.dll.
+  Windows API functions mciSendString, waveOutGetVolume,
+  waveOutSetVolume and PlaySound which are exported by Winmm.dll.
 */
 
 #include <config.h>
@@ -91,6 +89,11 @@ Copyright (C) 1998-1999, 2001-2024 Free Software Foundation, Inc.
 #include "w32.h"
 /* END: Windows Specific Includes */
 
+/* Missing in mingw32.  */
+#ifndef SND_SENTRY
+#define SND_SENTRY 0x00080000
+#endif
+
 #endif /* WINDOWSNT */
 
 /* BEGIN: Common Definitions */
@@ -278,7 +281,7 @@ #define MAX_SOUND_HEADER_BYTES \
 #else /* WINDOWSNT */
 
 /* BEGIN: Windows Specific Definitions */
-static int do_play_sound (const char *, unsigned long);
+static int do_play_sound (const char *, unsigned long, bool);
 /*
   END: Windows Specific Definitions */
 #endif /* WINDOWSNT */
@@ -366,21 +369,10 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs)
   attrs[SOUND_DEVICE] = plist_get (sound, QCdevice);
   attrs[SOUND_VOLUME] = plist_get (sound, QCvolume);
 
-#ifndef WINDOWSNT
   /* File name or data must be specified.  */
   if (!STRINGP (attrs[SOUND_FILE])
       && !STRINGP (attrs[SOUND_DATA]))
     return 0;
-#else /* WINDOWSNT */
-  /*
-    Data is not supported in Windows.  Therefore a
-    File name MUST be supplied.
-  */
-  if (!STRINGP (attrs[SOUND_FILE]))
-    {
-      return 0;
-    }
-#endif /* WINDOWSNT */
 
   /* Volume must be in the range 0..100 or unspecified.  */
   if (!NILP (attrs[SOUND_VOLUME]))
@@ -1225,7 +1217,7 @@ #define SOUND_WARNING(func, error, text)		\
   } while (0)
 
 static int
-do_play_sound (const char *psz_file, unsigned long ui_volume)
+do_play_sound (const char *psz_file_or_data, unsigned long ui_volume, bool in_memory)
 {
   int i_result = 0;
   MCIERROR mci_error = 0;
@@ -1236,65 +1228,7 @@ do_play_sound (const char *psz_file, unsigned long ui_volume)
   BOOL b_reset_volume = FALSE;
   char warn_text[560];
 
-  /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
-     need to encode the file in the ANSI codepage on Windows 9X even
-     if w32_unicode_filenames is non-zero.  */
-  if (w32_major_version <= 4 || !w32_unicode_filenames)
-    {
-      char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
-
-      filename_to_ansi (psz_file, fname_a);
-      fname_to_use = fname_a;
-      /* If the file name is not encodable in ANSI, try its short 8+3
-	 alias.  This will only work if w32_unicode_filenames is
-	 non-zero.  */
-      if (_mbspbrk ((const unsigned char *)fname_a,
-		    (const unsigned char *)"?"))
-	{
-	  if (w32_get_short_filename (psz_file, shortname, MAX_PATH))
-	    fname_to_use = shortname;
-	  else
-	    mci_error = MCIERR_FILE_NOT_FOUND;
-	}
-
-      if (!mci_error)
-	{
-	  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-	  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-	  sprintf (sz_cmd_buf_a,
-		   "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
-		   fname_to_use);
-	  mci_error = mciSendStringA (sz_cmd_buf_a,
-				      sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
-	}
-    }
-  else
-    {
-      wchar_t sz_cmd_buf_w[520];
-      wchar_t sz_ret_buf_w[520];
-      wchar_t fname_w[MAX_PATH];
-
-      filename_to_utf16 (psz_file, fname_w);
-      memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
-      memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
-      /* _swprintf is not available on Windows 9X, so we construct the
-	 UTF-16 command string by hand.  */
-      wcscpy (sz_cmd_buf_w, L"open \"");
-      wcscat (sz_cmd_buf_w, fname_w);
-      wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
-      mci_error = mciSendStringW (sz_cmd_buf_w,
-				  sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
-    }
-  if (mci_error != 0)
-    {
-      strcpy (warn_text,
-	      "mciSendString: 'open' command failed to open sound file ");
-      strcat (warn_text, psz_file);
-      SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
-      i_result = (int) mci_error;
-      return i_result;
-    }
-  if ((ui_volume > 0) && (ui_volume != UINT_MAX))
+  if (ui_volume > 0)
     {
       mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org);
       if (mm_result == MMSYSERR_NOERROR)
@@ -1319,34 +1253,105 @@ do_play_sound (const char *psz_file, unsigned long ui_volume)
                          " not be used.");
         }
     }
-  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-  strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
-  mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
-			      NULL);
-  if (mci_error != 0)
+
+  if (in_memory)
     {
-      strcpy (warn_text,
-	      "mciSendString: 'play' command failed to play sound file ");
-      strcat (warn_text, psz_file);
-      SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
-      i_result = (int) mci_error;
+      int flags = SND_MEMORY;
+      if (w32_major_version >= 6) /* Vista and later */
+	flags |= SND_SENTRY;
+      i_result = !PlaySound (psz_file_or_data, NULL, flags);
     }
-  memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
-  memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
-  strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
-  mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
-			      NULL);
+  else
+    {
+      /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
+	 need to encode the file in the ANSI codepage on Windows 9X even
+	 if w32_unicode_filenames is non-zero.  */
+      if (w32_major_version <= 4 || !w32_unicode_filenames)
+	{
+	  char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
+
+	  filename_to_ansi (psz_file_or_data, fname_a);
+	  fname_to_use = fname_a;
+	  /* If the file name is not encodable in ANSI, try its short 8+3
+	     alias.  This will only work if w32_unicode_filenames is
+	     non-zero.  */
+	  if (_mbspbrk ((const unsigned char *)fname_a,
+			(const unsigned char *)"?"))
+	    {
+	      if (w32_get_short_filename (psz_file_or_data, shortname, MAX_PATH))
+		fname_to_use = shortname;
+	      else
+		mci_error = MCIERR_FILE_NOT_FOUND;
+	    }
+
+	  if (!mci_error)
+	    {
+	      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+	      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+	      sprintf (sz_cmd_buf_a,
+		       "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
+		       fname_to_use);
+	      mci_error = mciSendStringA (sz_cmd_buf_a,
+					  sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
+	    }
+	}
+      else
+	{
+	  wchar_t sz_cmd_buf_w[520];
+	  wchar_t sz_ret_buf_w[520];
+	  wchar_t fname_w[MAX_PATH];
+
+	  filename_to_utf16 (psz_file_or_data, fname_w);
+	  memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
+	  memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
+	  /* _swprintf is not available on Windows 9X, so we construct the
+	     UTF-16 command string by hand.  */
+	  wcscpy (sz_cmd_buf_w, L"open \"");
+	  wcscat (sz_cmd_buf_w, fname_w);
+	  wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
+	  mci_error = mciSendStringW (sz_cmd_buf_w,
+				      sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
+	}
+      if (mci_error != 0)
+	{
+	  strcpy (warn_text,
+		  "mciSendString: 'open' command failed to open sound file ");
+	  strcat (warn_text, psz_file_or_data);
+	  SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
+	  i_result = (int) mci_error;
+	  return i_result;
+	}
+      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+      strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
+      mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
+				  NULL);
+      if (mci_error != 0)
+	{
+	  strcpy (warn_text,
+		  "mciSendString: 'play' command failed to play sound file ");
+	  strcat (warn_text, psz_file_or_data);
+	  SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
+	  i_result = (int) mci_error;
+	}
+      memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
+      memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
+      strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
+      mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
+				  NULL);
+    }
+
   if (b_reset_volume == TRUE)
     {
       mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org);
       if (mm_result != MMSYSERR_NOERROR)
-        {
-          SOUND_WARNING (waveOutGetErrorText, mm_result,
+	{
+	  SOUND_WARNING (waveOutGetErrorText, mm_result,
 			 "waveOutSetVolume: failed to reset the original"
-                         " volume level of the WAVE_MAPPER device.");
-        }
+			 " volume level of the WAVE_MAPPER device.");
+	}
     }
+
   return i_result;
 }
 
@@ -1364,8 +1369,7 @@ DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1,
   specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
-  unsigned long ui_volume_tmp = UINT_MAX;
-  unsigned long ui_volume = UINT_MAX;
+  unsigned long ui_volume = 0;
 #endif /* WINDOWSNT */
 
   /* Parse the sound specification.  Give up if it is invalid.  */
@@ -1432,33 +1436,31 @@ DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1,
 
 #else /* WINDOWSNT */
 
-  file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
-  file = ENCODE_FILE (file);
+
   if (FIXNUMP (attrs[SOUND_VOLUME]))
-    {
-      ui_volume_tmp = XFIXNAT (attrs[SOUND_VOLUME]);
-    }
+    ui_volume = XFIXNAT (attrs[SOUND_VOLUME]);
   else if (FLOATP (attrs[SOUND_VOLUME]))
-    {
-      ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
-    }
+    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);
 
-  /*
-    Based on some experiments I have conducted, a value of 100 or less
-    for the sound volume is much too low.  You cannot even hear it.
-    A value of UINT_MAX indicates that you wish for the sound to played
-    at the maximum possible volume.  A value of UINT_MAX/2 plays the
-    sound at 50% maximum volume.  Therefore the value passed to do_play_sound
-    (and thus to waveOutSetVolume) must be some fraction of UINT_MAX.
-    The following code adjusts the user specified volume level appropriately.
-  */
-  if ((ui_volume_tmp > 0) && (ui_volume_tmp <= 100))
+  if (STRINGP (attrs[SOUND_FILE]))
     {
-      ui_volume = ui_volume_tmp * (UINT_MAX / 100);
+      file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
+      file = ENCODE_FILE (file);
+      do_play_sound (SSDATA (file), ui_volume, false);
     }
-  (void)do_play_sound (SSDATA (file), ui_volume);
+  else
+    do_play_sound (SDATA (attrs[SOUND_DATA]), ui_volume, true);
 
 #endif /* WINDOWSNT */
 
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 18:33       ` Cecilio Pardo
@ 2024-12-15 18:48         ` Eli Zaretskii
  2024-12-15 20:38           ` Cecilio Pardo
  2024-12-21 10:37         ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2024-12-15 18:48 UTC (permalink / raw)
  To: Cecilio Pardo; +Cc: 74863

> Date: Sun, 15 Dec 2024 19:33:35 +0100
> Cc: 74863@debbugs.gnu.org
> From: Cecilio Pardo <cpardo@imayhem.com>
> 
> >> +  if (in_memory)
> >> +    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);
> > 
> > AFAIU, the documentation seems to say that the string passed as the
> > first argument to PlaySound is limited to 256 characters (i.e. bytes)?
> > If so, how do we play longer sounds?
> 
> I think this limitation applies only when the argument points to a 
> string, and not when using SND_MEMORY, which is documented with: "The 
> pszSound parameter points to a sound loaded in memory."
> 
> It's true the documentation doesn't say so, and I haven't found any 
> clarification by Microsoft, but SND_MEMORY would be useless otherwise. 
> Also I see normal usage searching the internet.

So there are no limitations whatsoever on the length of that string?





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15  1:35       ` Stefan Kangas
@ 2024-12-15 20:36         ` Cecilio Pardo
  2024-12-15 22:16           ` Stefan Kangas
  0 siblings, 1 reply; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-15 20:36 UTC (permalink / raw)
  To: Stefan Kangas, Eli Zaretskii; +Cc: 74863

On 15/12/2024 2:35, Stefan Kangas wrote:
> Eli Zaretskii <eliz@gnu.org> writes:
> 
>>> Should we add support for PipeWire on GNU/Linux?
> 
> ALSA clients can be configured to output via PipeWire, and the Pipewire
> project itself recommends staying with the ALSA API, at least for now:
> 
> https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#what-audio-api-do-you-recommend-to-use
> 
>> I don't know what PipeWire is, so I have no opinion on this.
> 
> It's a new multimedia server that replaces both Pulse Audio and JACK.
> AFAIK, it's the default sound server on Debian when using Gnome, and on
> Fedora 34.

Thank you.

I expected this to be easier to make async, but will try with alsa.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 18:48         ` Eli Zaretskii
@ 2024-12-15 20:38           ` Cecilio Pardo
  0 siblings, 0 replies; 13+ messages in thread
From: Cecilio Pardo @ 2024-12-15 20:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 74863



On 15/12/2024 19:48, Eli Zaretskii wrote:
>> Date: Sun, 15 Dec 2024 19:33:35 +0100
>> Cc: 74863@debbugs.gnu.org
>> From: Cecilio Pardo <cpardo@imayhem.com>
>>
>>>> +  if (in_memory)
>>>> +    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);
>>>
>>> AFAIU, the documentation seems to say that the string passed as the
>>> first argument to PlaySound is limited to 256 characters (i.e. bytes)?
>>> If so, how do we play longer sounds?
>>
>> I think this limitation applies only when the argument points to a
>> string, and not when using SND_MEMORY, which is documented with: "The
>> pszSound parameter points to a sound loaded in memory."
>>
>> It's true the documentation doesn't say so, and I haven't found any
>> clarification by Microsoft, but SND_MEMORY would be useless otherwise.
>> Also I see normal usage searching the internet.
> 
> So there are no limitations whatsoever on the length of that string?

Everything (except the documentation) points to that.






^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 20:36         ` Cecilio Pardo
@ 2024-12-15 22:16           ` Stefan Kangas
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Kangas @ 2024-12-15 22:16 UTC (permalink / raw)
  To: Cecilio Pardo, Eli Zaretskii; +Cc: 74863

Cecilio Pardo <cpardo@imayhem.com> writes:

> On 15/12/2024 2:35, Stefan Kangas wrote:
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>>>> Should we add support for PipeWire on GNU/Linux?
>>
>> ALSA clients can be configured to output via PipeWire, and the Pipewire
>> project itself recommends staying with the ALSA API, at least for now:
>>
>> https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#what-audio-api-do-you-recommend-to-use
>>
>>> I don't know what PipeWire is, so I have no opinion on this.
>>
>> It's a new multimedia server that replaces both Pulse Audio and JACK.
>> AFAIK, it's the default sound server on Debian when using Gnome, and on
>> Fedora 34.
>
> Thank you.
>
> I expected this to be easier to make async, but will try with alsa.

Thanks for working on this.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* bug#74863: 31.0.50; Problems with play-sound on MS-Windows
  2024-12-15 18:33       ` Cecilio Pardo
  2024-12-15 18:48         ` Eli Zaretskii
@ 2024-12-21 10:37         ` Eli Zaretskii
  1 sibling, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2024-12-21 10:37 UTC (permalink / raw)
  To: Cecilio Pardo; +Cc: 74863-done

> Date: Sun, 15 Dec 2024 19:33:35 +0100
> Cc: 74863@debbugs.gnu.org
> From: Cecilio Pardo <cpardo@imayhem.com>
> 
> On 15/12/2024 13:50, Eli Zaretskii wrote:
> 
> >> (defun load-file-into-unibyte-string (file-path)
> >>     (with-temp-buffer
> >>       (set-buffer-multibyte nil)
> >>       (insert-file-contents file-path)
> >>       (buffer-string)))
> >>
> >> (play-sound `(sound :data ,(load-file-into-unibyte-string "awav.wav")
> >> :volume 100))
> > 
> > What's wrong with insert-file-contents-literally?
> 
> Nothing. So many functions...
> 
> > 
> >> +  if (in_memory)
> >> +    i_result = !PlaySound (psz_file_or_data, NULL, SND_MEMORY);
> > 
> > AFAIU, the documentation seems to say that the string passed as the
> > first argument to PlaySound is limited to 256 characters (i.e. bytes)?
> > If so, how do we play longer sounds?
> 
> I think this limitation applies only when the argument points to a 
> string, and not when using SND_MEMORY, which is documented with: "The 
> pszSound parameter points to a sound loaded in memory."
> 
> It's true the documentation doesn't say so, and I haven't found any 
> clarification by Microsoft, but SND_MEMORY would be useless otherwise. 
> Also I see normal usage searching the internet.
> 
> > Should we also use SND_SENTRY flag (on Vista and later)?
> 
> Yes, done in the attached patch.

Thanks, installed on master, and closing the bug.





^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-12-21 10:37 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-13 23:50 bug#74863: 31.0.50; Problems with play-sound on MS-Windows Cecilio Pardo
2024-12-14  8:42 ` Eli Zaretskii
2024-12-14 14:07   ` Cecilio Pardo
2024-12-14 14:56     ` Eli Zaretskii
2024-12-15  1:35       ` Stefan Kangas
2024-12-15 20:36         ` Cecilio Pardo
2024-12-15 22:16           ` Stefan Kangas
2024-12-15 11:55   ` Cecilio Pardo
2024-12-15 12:50     ` Eli Zaretskii
2024-12-15 18:33       ` Cecilio Pardo
2024-12-15 18:48         ` Eli Zaretskii
2024-12-15 20:38           ` Cecilio Pardo
2024-12-21 10:37         ` Eli Zaretskii

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.