diff options
| author | Cecilio Pardo | 2024-12-15 01:13:16 +0100 |
|---|---|---|
| committer | Eli Zaretskii | 2024-12-21 12:35:09 +0200 |
| commit | fd529bbd076d14087d70c50d94bc9ef231cf1997 (patch) | |
| tree | 446f92ac0062c3ba335d6286703cda9904722bcd | |
| parent | b6852b67b0d462c7ba0012e5ac3b79a245f4b7e5 (diff) | |
| download | emacs-fd529bbd076d14087d70c50d94bc9ef231cf1997.tar.gz emacs-fd529bbd076d14087d70c50d94bc9ef231cf1997.zip | |
Add support for the ':data' keyword for play-sound in MS-Windows.
* src/sound.c (parse_sound) [WINDOWSNT]: 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'. (Bug#74863)
* etc/NEWS: Add entry for this change.
* etc/PROBLEMS: Remove entry about missing support for :data.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | etc/PROBLEMS | 5 | ||||
| -rw-r--r-- | src/sound.c | 242 |
3 files changed, 127 insertions, 125 deletions
| @@ -1111,6 +1111,11 @@ current buffer, if the major mode supports it. (Support for | |||
| 1111 | Transformed images are smoothed using the bilinear interpolation by | 1111 | Transformed images are smoothed using the bilinear interpolation by |
| 1112 | means of the GDI+ library. | 1112 | means of the GDI+ library. |
| 1113 | 1113 | ||
| 1114 | --- | ||
| 1115 | ** Emacs on MS-Windows now supports the ':data' keyword for 'play-sound'. | ||
| 1116 | In addition to ':file FILE' for playing a sound from a file, ':data | ||
| 1117 | DATA' can now be used to play a sound from memory. | ||
| 1118 | |||
| 1114 | 1119 | ||
| 1115 | ---------------------------------------------------------------------- | 1120 | ---------------------------------------------------------------------- |
| 1116 | This file is part of GNU Emacs. | 1121 | 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 | |||
| 3278 | well, since the Windows port uses a Lisp emulation of 'ls', which relies | 3278 | well, since the Windows port uses a Lisp emulation of 'ls', which relies |
| 3279 | on 'file-attributes'. | 3279 | on 'file-attributes'. |
| 3280 | 3280 | ||
| 3281 | ** Playing sound doesn't support the :data method | ||
| 3282 | |||
| 3283 | Sound playing is not supported with the ':data DATA' key-value pair. | ||
| 3284 | You _must_ use the ':file FILE' method. | ||
| 3285 | |||
| 3286 | ** Typing Alt-Shift has strange effects on MS-Windows. | 3281 | ** Typing Alt-Shift has strange effects on MS-Windows. |
| 3287 | 3282 | ||
| 3288 | This combination of keys is a command to change keyboard layout. If | 3283 | 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 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 26 | implementation of the play-sound specification for Windows. | 26 | implementation of the play-sound specification for Windows. |
| 27 | 27 | ||
| 28 | Notes: | 28 | Notes: |
| 29 | In the Windows implementation of play-sound-internal only the | 29 | In the Windows implementation of play-sound-internal the :device |
| 30 | :file and :volume keywords are supported. The :device keyword, | 30 | keyword, if present, is ignored. |
| 31 | if present, is ignored. The :data keyword, if present, will | ||
| 32 | cause an error to be generated. | ||
| 33 | 31 | ||
| 34 | The Windows implementation of play-sound is implemented via the | 32 | The Windows implementation of play-sound is implemented via the |
| 35 | Windows API functions mciSendString, waveOutGetVolume, and | 33 | Windows API functions mciSendString, waveOutGetVolume, |
| 36 | waveOutSetVolume which are exported by Winmm.dll. | 34 | waveOutSetVolume and PlaySound which are exported by Winmm.dll. |
| 37 | */ | 35 | */ |
| 38 | 36 | ||
| 39 | #include <config.h> | 37 | #include <config.h> |
| @@ -91,6 +89,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 91 | #include "w32.h" | 89 | #include "w32.h" |
| 92 | /* END: Windows Specific Includes */ | 90 | /* END: Windows Specific Includes */ |
| 93 | 91 | ||
| 92 | /* Missing in mingw32. */ | ||
| 93 | #ifndef SND_SENTRY | ||
| 94 | #define SND_SENTRY 0x00080000 | ||
| 95 | #endif | ||
| 96 | |||
| 94 | #endif /* WINDOWSNT */ | 97 | #endif /* WINDOWSNT */ |
| 95 | 98 | ||
| 96 | /* BEGIN: Common Definitions */ | 99 | /* BEGIN: Common Definitions */ |
| @@ -278,7 +281,7 @@ static void au_play (struct sound *, struct sound_device *); | |||
| 278 | #else /* WINDOWSNT */ | 281 | #else /* WINDOWSNT */ |
| 279 | 282 | ||
| 280 | /* BEGIN: Windows Specific Definitions */ | 283 | /* BEGIN: Windows Specific Definitions */ |
| 281 | static int do_play_sound (const char *, unsigned long); | 284 | static int do_play_sound (const char *, unsigned long, bool); |
| 282 | /* | 285 | /* |
| 283 | END: Windows Specific Definitions */ | 286 | END: Windows Specific Definitions */ |
| 284 | #endif /* WINDOWSNT */ | 287 | #endif /* WINDOWSNT */ |
| @@ -366,21 +369,10 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs) | |||
| 366 | attrs[SOUND_DEVICE] = plist_get (sound, QCdevice); | 369 | attrs[SOUND_DEVICE] = plist_get (sound, QCdevice); |
| 367 | attrs[SOUND_VOLUME] = plist_get (sound, QCvolume); | 370 | attrs[SOUND_VOLUME] = plist_get (sound, QCvolume); |
| 368 | 371 | ||
| 369 | #ifndef WINDOWSNT | ||
| 370 | /* File name or data must be specified. */ | 372 | /* File name or data must be specified. */ |
| 371 | if (!STRINGP (attrs[SOUND_FILE]) | 373 | if (!STRINGP (attrs[SOUND_FILE]) |
| 372 | && !STRINGP (attrs[SOUND_DATA])) | 374 | && !STRINGP (attrs[SOUND_DATA])) |
| 373 | return 0; | 375 | return 0; |
| 374 | #else /* WINDOWSNT */ | ||
| 375 | /* | ||
| 376 | Data is not supported in Windows. Therefore a | ||
| 377 | File name MUST be supplied. | ||
| 378 | */ | ||
| 379 | if (!STRINGP (attrs[SOUND_FILE])) | ||
| 380 | { | ||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | #endif /* WINDOWSNT */ | ||
| 384 | 376 | ||
| 385 | /* Volume must be in the range 0..100 or unspecified. */ | 377 | /* Volume must be in the range 0..100 or unspecified. */ |
| 386 | if (!NILP (attrs[SOUND_VOLUME])) | 378 | if (!NILP (attrs[SOUND_VOLUME])) |
| @@ -1225,7 +1217,7 @@ alsa_init (struct sound_device *sd) | |||
| 1225 | } while (0) | 1217 | } while (0) |
| 1226 | 1218 | ||
| 1227 | static int | 1219 | static int |
| 1228 | do_play_sound (const char *psz_file, unsigned long ui_volume) | 1220 | do_play_sound (const char *psz_file_or_data, unsigned long ui_volume, bool in_memory) |
| 1229 | { | 1221 | { |
| 1230 | int i_result = 0; | 1222 | int i_result = 0; |
| 1231 | MCIERROR mci_error = 0; | 1223 | MCIERROR mci_error = 0; |
| @@ -1236,65 +1228,7 @@ do_play_sound (const char *psz_file, unsigned long ui_volume) | |||
| 1236 | BOOL b_reset_volume = FALSE; | 1228 | BOOL b_reset_volume = FALSE; |
| 1237 | char warn_text[560]; | 1229 | char warn_text[560]; |
| 1238 | 1230 | ||
| 1239 | /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we | 1231 | if (ui_volume > 0) |
| 1240 | need to encode the file in the ANSI codepage on Windows 9X even | ||
| 1241 | if w32_unicode_filenames is non-zero. */ | ||
| 1242 | if (w32_major_version <= 4 || !w32_unicode_filenames) | ||
| 1243 | { | ||
| 1244 | char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use; | ||
| 1245 | |||
| 1246 | filename_to_ansi (psz_file, fname_a); | ||
| 1247 | fname_to_use = fname_a; | ||
| 1248 | /* If the file name is not encodable in ANSI, try its short 8+3 | ||
| 1249 | alias. This will only work if w32_unicode_filenames is | ||
| 1250 | non-zero. */ | ||
| 1251 | if (_mbspbrk ((const unsigned char *)fname_a, | ||
| 1252 | (const unsigned char *)"?")) | ||
| 1253 | { | ||
| 1254 | if (w32_get_short_filename (psz_file, shortname, MAX_PATH)) | ||
| 1255 | fname_to_use = shortname; | ||
| 1256 | else | ||
| 1257 | mci_error = MCIERR_FILE_NOT_FOUND; | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | if (!mci_error) | ||
| 1261 | { | ||
| 1262 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | ||
| 1263 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | ||
| 1264 | sprintf (sz_cmd_buf_a, | ||
| 1265 | "open \"%s\" alias GNUEmacs_PlaySound_Device wait", | ||
| 1266 | fname_to_use); | ||
| 1267 | mci_error = mciSendStringA (sz_cmd_buf_a, | ||
| 1268 | sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); | ||
| 1269 | } | ||
| 1270 | } | ||
| 1271 | else | ||
| 1272 | { | ||
| 1273 | wchar_t sz_cmd_buf_w[520]; | ||
| 1274 | wchar_t sz_ret_buf_w[520]; | ||
| 1275 | wchar_t fname_w[MAX_PATH]; | ||
| 1276 | |||
| 1277 | filename_to_utf16 (psz_file, fname_w); | ||
| 1278 | memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w)); | ||
| 1279 | memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w)); | ||
| 1280 | /* _swprintf is not available on Windows 9X, so we construct the | ||
| 1281 | UTF-16 command string by hand. */ | ||
| 1282 | wcscpy (sz_cmd_buf_w, L"open \""); | ||
| 1283 | wcscat (sz_cmd_buf_w, fname_w); | ||
| 1284 | wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait"); | ||
| 1285 | mci_error = mciSendStringW (sz_cmd_buf_w, | ||
| 1286 | sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL); | ||
| 1287 | } | ||
| 1288 | if (mci_error != 0) | ||
| 1289 | { | ||
| 1290 | strcpy (warn_text, | ||
| 1291 | "mciSendString: 'open' command failed to open sound file "); | ||
| 1292 | strcat (warn_text, psz_file); | ||
| 1293 | SOUND_WARNING (mciGetErrorString, mci_error, warn_text); | ||
| 1294 | i_result = (int) mci_error; | ||
| 1295 | return i_result; | ||
| 1296 | } | ||
| 1297 | if ((ui_volume > 0) && (ui_volume != UINT_MAX)) | ||
| 1298 | { | 1232 | { |
| 1299 | mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org); | 1233 | mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org); |
| 1300 | if (mm_result == MMSYSERR_NOERROR) | 1234 | if (mm_result == MMSYSERR_NOERROR) |
| @@ -1319,34 +1253,105 @@ do_play_sound (const char *psz_file, unsigned long ui_volume) | |||
| 1319 | " not be used."); | 1253 | " not be used."); |
| 1320 | } | 1254 | } |
| 1321 | } | 1255 | } |
| 1322 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | 1256 | |
| 1323 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | 1257 | if (in_memory) |
| 1324 | strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait"); | ||
| 1325 | mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), | ||
| 1326 | NULL); | ||
| 1327 | if (mci_error != 0) | ||
| 1328 | { | 1258 | { |
| 1329 | strcpy (warn_text, | 1259 | int flags = SND_MEMORY; |
| 1330 | "mciSendString: 'play' command failed to play sound file "); | 1260 | if (w32_major_version >= 6) /* Vista and later */ |
| 1331 | strcat (warn_text, psz_file); | 1261 | flags |= SND_SENTRY; |
| 1332 | SOUND_WARNING (mciGetErrorString, mci_error, warn_text); | 1262 | i_result = !PlaySound (psz_file_or_data, NULL, flags); |
| 1333 | i_result = (int) mci_error; | ||
| 1334 | } | 1263 | } |
| 1335 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | 1264 | else |
| 1336 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | 1265 | { |
| 1337 | strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait"); | 1266 | /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we |
| 1338 | mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), | 1267 | need to encode the file in the ANSI codepage on Windows 9X even |
| 1339 | NULL); | 1268 | if w32_unicode_filenames is non-zero. */ |
| 1269 | if (w32_major_version <= 4 || !w32_unicode_filenames) | ||
| 1270 | { | ||
| 1271 | char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use; | ||
| 1272 | |||
| 1273 | filename_to_ansi (psz_file_or_data, fname_a); | ||
| 1274 | fname_to_use = fname_a; | ||
| 1275 | /* If the file name is not encodable in ANSI, try its short 8+3 | ||
| 1276 | alias. This will only work if w32_unicode_filenames is | ||
| 1277 | non-zero. */ | ||
| 1278 | if (_mbspbrk ((const unsigned char *)fname_a, | ||
| 1279 | (const unsigned char *)"?")) | ||
| 1280 | { | ||
| 1281 | if (w32_get_short_filename (psz_file_or_data, shortname, MAX_PATH)) | ||
| 1282 | fname_to_use = shortname; | ||
| 1283 | else | ||
| 1284 | mci_error = MCIERR_FILE_NOT_FOUND; | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | if (!mci_error) | ||
| 1288 | { | ||
| 1289 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | ||
| 1290 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | ||
| 1291 | sprintf (sz_cmd_buf_a, | ||
| 1292 | "open \"%s\" alias GNUEmacs_PlaySound_Device wait", | ||
| 1293 | fname_to_use); | ||
| 1294 | mci_error = mciSendStringA (sz_cmd_buf_a, | ||
| 1295 | sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); | ||
| 1296 | } | ||
| 1297 | } | ||
| 1298 | else | ||
| 1299 | { | ||
| 1300 | wchar_t sz_cmd_buf_w[520]; | ||
| 1301 | wchar_t sz_ret_buf_w[520]; | ||
| 1302 | wchar_t fname_w[MAX_PATH]; | ||
| 1303 | |||
| 1304 | filename_to_utf16 (psz_file_or_data, fname_w); | ||
| 1305 | memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w)); | ||
| 1306 | memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w)); | ||
| 1307 | /* _swprintf is not available on Windows 9X, so we construct the | ||
| 1308 | UTF-16 command string by hand. */ | ||
| 1309 | wcscpy (sz_cmd_buf_w, L"open \""); | ||
| 1310 | wcscat (sz_cmd_buf_w, fname_w); | ||
| 1311 | wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait"); | ||
| 1312 | mci_error = mciSendStringW (sz_cmd_buf_w, | ||
| 1313 | sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL); | ||
| 1314 | } | ||
| 1315 | if (mci_error != 0) | ||
| 1316 | { | ||
| 1317 | strcpy (warn_text, | ||
| 1318 | "mciSendString: 'open' command failed to open sound file "); | ||
| 1319 | strcat (warn_text, psz_file_or_data); | ||
| 1320 | SOUND_WARNING (mciGetErrorString, mci_error, warn_text); | ||
| 1321 | i_result = (int) mci_error; | ||
| 1322 | return i_result; | ||
| 1323 | } | ||
| 1324 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | ||
| 1325 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | ||
| 1326 | strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait"); | ||
| 1327 | mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), | ||
| 1328 | NULL); | ||
| 1329 | if (mci_error != 0) | ||
| 1330 | { | ||
| 1331 | strcpy (warn_text, | ||
| 1332 | "mciSendString: 'play' command failed to play sound file "); | ||
| 1333 | strcat (warn_text, psz_file_or_data); | ||
| 1334 | SOUND_WARNING (mciGetErrorString, mci_error, warn_text); | ||
| 1335 | i_result = (int) mci_error; | ||
| 1336 | } | ||
| 1337 | memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); | ||
| 1338 | memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); | ||
| 1339 | strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait"); | ||
| 1340 | mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), | ||
| 1341 | NULL); | ||
| 1342 | } | ||
| 1343 | |||
| 1340 | if (b_reset_volume == TRUE) | 1344 | if (b_reset_volume == TRUE) |
| 1341 | { | 1345 | { |
| 1342 | mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org); | 1346 | mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org); |
| 1343 | if (mm_result != MMSYSERR_NOERROR) | 1347 | if (mm_result != MMSYSERR_NOERROR) |
| 1344 | { | 1348 | { |
| 1345 | SOUND_WARNING (waveOutGetErrorText, mm_result, | 1349 | SOUND_WARNING (waveOutGetErrorText, mm_result, |
| 1346 | "waveOutSetVolume: failed to reset the original" | 1350 | "waveOutSetVolume: failed to reset the original" |
| 1347 | " volume level of the WAVE_MAPPER device."); | 1351 | " volume level of the WAVE_MAPPER device."); |
| 1348 | } | 1352 | } |
| 1349 | } | 1353 | } |
| 1354 | |||
| 1350 | return i_result; | 1355 | return i_result; |
| 1351 | } | 1356 | } |
| 1352 | 1357 | ||
| @@ -1364,8 +1369,7 @@ Internal use only, use `play-sound' instead. */) | |||
| 1364 | specpdl_ref count = SPECPDL_INDEX (); | 1369 | specpdl_ref count = SPECPDL_INDEX (); |
| 1365 | 1370 | ||
| 1366 | #ifdef WINDOWSNT | 1371 | #ifdef WINDOWSNT |
| 1367 | unsigned long ui_volume_tmp = UINT_MAX; | 1372 | unsigned long ui_volume = 0; |
| 1368 | unsigned long ui_volume = UINT_MAX; | ||
| 1369 | #endif /* WINDOWSNT */ | 1373 | #endif /* WINDOWSNT */ |
| 1370 | 1374 | ||
| 1371 | /* Parse the sound specification. Give up if it is invalid. */ | 1375 | /* Parse the sound specification. Give up if it is invalid. */ |
| @@ -1432,33 +1436,31 @@ Internal use only, use `play-sound' instead. */) | |||
| 1432 | 1436 | ||
| 1433 | #else /* WINDOWSNT */ | 1437 | #else /* WINDOWSNT */ |
| 1434 | 1438 | ||
| 1435 | file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory); | 1439 | |
| 1436 | file = ENCODE_FILE (file); | ||
| 1437 | if (FIXNUMP (attrs[SOUND_VOLUME])) | 1440 | if (FIXNUMP (attrs[SOUND_VOLUME])) |
| 1438 | { | 1441 | ui_volume = XFIXNAT (attrs[SOUND_VOLUME]); |
| 1439 | ui_volume_tmp = XFIXNAT (attrs[SOUND_VOLUME]); | ||
| 1440 | } | ||
| 1441 | else if (FLOATP (attrs[SOUND_VOLUME])) | 1442 | else if (FLOATP (attrs[SOUND_VOLUME])) |
| 1442 | { | 1443 | ui_volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100; |
| 1443 | ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100; | 1444 | |
| 1444 | } | 1445 | if (ui_volume > 100) |
| 1446 | ui_volume = 100; | ||
| 1447 | |||
| 1448 | /* For volume (32 bits), low order 16 bits are the value for left | ||
| 1449 | channel, and high order 16 bits for the right channel. We use the | ||
| 1450 | specified volume on both channels. */ | ||
| 1451 | ui_volume = ui_volume * 0xFFFF / 100; | ||
| 1452 | ui_volume = (ui_volume << 16) + ui_volume; | ||
| 1445 | 1453 | ||
| 1446 | CALLN (Frun_hook_with_args, Qplay_sound_functions, sound); | 1454 | CALLN (Frun_hook_with_args, Qplay_sound_functions, sound); |
| 1447 | 1455 | ||
| 1448 | /* | 1456 | if (STRINGP (attrs[SOUND_FILE])) |
| 1449 | Based on some experiments I have conducted, a value of 100 or less | ||
| 1450 | for the sound volume is much too low. You cannot even hear it. | ||
| 1451 | A value of UINT_MAX indicates that you wish for the sound to played | ||
| 1452 | at the maximum possible volume. A value of UINT_MAX/2 plays the | ||
| 1453 | sound at 50% maximum volume. Therefore the value passed to do_play_sound | ||
| 1454 | (and thus to waveOutSetVolume) must be some fraction of UINT_MAX. | ||
| 1455 | The following code adjusts the user specified volume level appropriately. | ||
| 1456 | */ | ||
| 1457 | if ((ui_volume_tmp > 0) && (ui_volume_tmp <= 100)) | ||
| 1458 | { | 1457 | { |
| 1459 | ui_volume = ui_volume_tmp * (UINT_MAX / 100); | 1458 | file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory); |
| 1459 | file = ENCODE_FILE (file); | ||
| 1460 | do_play_sound (SSDATA (file), ui_volume, false); | ||
| 1460 | } | 1461 | } |
| 1461 | (void)do_play_sound (SSDATA (file), ui_volume); | 1462 | else |
| 1463 | do_play_sound (SDATA (attrs[SOUND_DATA]), ui_volume, true); | ||
| 1462 | 1464 | ||
| 1463 | #endif /* WINDOWSNT */ | 1465 | #endif /* WINDOWSNT */ |
| 1464 | 1466 | ||