Package: emacs;
Reported by: Alex Schröder <kensanata <at> gmail.com>
Date: Fri, 22 May 2009 13:40:04 UTC
Severity: wishlist
View this message in rfc822 format
From: YAMAMOTO Mitsuharu <mituharu <at> math.s.chiba-u.ac.jp> To: Leo Liu <sdl.web <at> gmail.com> Cc: Alex Schröder <kensanata <at> gmail.com>, 3351 <at> debbugs.gnu.org Subject: bug#3351: 23.0.93; OSX sound support Date: Sun, 17 Mar 2013 17:36:31 +0900
>>>>> On Fri, 15 Mar 2013 18:25:25 +0800, Leo Liu <sdl.web <at> gmail.com> said: > On 2009-05-22 21:31 +0800, Alex Schröder wrote: >> In GNU Emacs 23.0.93.2 (i386-apple-darwin8.11.1, NS apple-appkit-824.48) >> of 2009-05-22 on Pyrobombus.local >> Windowing system distributor `Apple', version 10.3.824 >> configured using `configure '--with-ns'' >> >> I'm using Mac OS 10.4.11 and when I try to (play-sound '(sound :file >> "/some/file")) I get the error "This Emacs binary lacks sound >> support". >> >> I think no Emacs is complete without sound support. ;) > I am using this small function to give me sound support on OSX: > https://raw.github.com/leoliu/play-sound-osx/master/play-sound.el > Two conscious abuses (can be fixed): > - misuse (signal 'wrong-type-argument (list sound)); it requires the > first item of DATA to be a predicate but I decided not to add another > function. > - async; should probably use call-process to stay close to the C > version. > BTW, I only remember once in the past years needing the feature. Below is a quick hack for the Mac port (*) to have sound support. Perhaps one may use this as a hint. *: http://lists.gnu.org/archive/html/emacs-devel/2013-03/msg00251.html YAMAMOTO Mitsuharu mituharu <at> math.s.chiba-u.ac.jp === modified file 'configure.ac' *** configure.ac 2013-03-11 03:49:04 +0000 --- configure.ac 2013-03-17 08:17:26 +0000 *************** *** 2752,2757 **** --- 2752,2758 ---- ### Use Mac OS X GUI. if test "${HAVE_MACGUI}" = "yes"; then AC_DEFINE(HAVE_MACGUI, 1, [Define to 1 if you are using GUI on Mac OS X.]) + AC_DEFINE(HAVE_SOUND, 1, [Define to 1 if you have sound support.]) AC_CHECK_HEADERS(AvailabilityMacros.h) MAC_CFLAGS="-fconstant-cfstrings" ## Specify the install directory === modified file 'src/macappkit.h' *** src/macappkit.h 2013-02-09 07:26:28 +0000 --- src/macappkit.h 2013-03-17 08:17:26 +0000 *************** *** 61,66 **** --- 61,67 ---- compiled on Mac OS X 10.5 fails in startup at -[EmacsController methodSignatureForSelector:] when executed on Mac OS X 10.6. */ @protocol NSApplicationDelegate @end + @protocol NSSoundDelegate @end @protocol NSWindowDelegate @end @protocol NSToolbarDelegate @end @protocol NSMenuDelegate @end *************** *** 194,199 **** --- 195,203 ---- /* Set of windows whose flush is deferred. */ NSMutableSet *deferredFlushWindows; + + /* Set of sounds currently being played. */ + NSMutableSet *soundsBeingPlayed; } - (int)getAndClearMenuItemSelection; - (void)storeInputEvent:(id)sender; *************** *** 691,696 **** --- 695,704 ---- #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */ + @interface EmacsController (Sound) <NSSoundDelegate> + - (void)addAndPlaySound:(NSSound *)sound; + @end + /* Some methods that are not declared in older versions. Should be used with some runtime check such as `respondsToSelector:'. */ *************** *** 868,870 **** --- 876,885 ---- @end #endif #endif + + #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + @interface NSSound (AvailableOn1050AndLater) + - (void)setVolume:(float)volume; + - (void)setPlaybackDeviceIdentifier:(NSString *)deviceUID; + @end + #endif === modified file 'src/macappkit.m' *** src/macappkit.m 2013-03-05 06:19:19 +0000 --- src/macappkit.m 2013-03-17 08:20:12 +0000 *************** *** 12207,12209 **** --- 12207,12270 ---- return result; } + + + /*********************************************************************** + Sound + ***********************************************************************/ + @implementation EmacsController (Sound) + + - (void)addAndPlaySound:(NSSound *)sound + { + if (soundsBeingPlayed == nil) + soundsBeingPlayed = [[NSMutableSet alloc] initWithCapacity:0]; + [soundsBeingPlayed addObject:sound]; + + [sound setDelegate:self]; + [sound play]; + } + + - (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finishedPlaying + { + [soundsBeingPlayed removeObject:sound]; + } + + @end + + CFTypeRef + mac_sound_create (Lisp_Object file, Lisp_Object data) + { + NSSound *sound; + + if (STRINGP (file)) + { + file = ENCODE_FILE (file); + sound = [[NSSound alloc] + initWithContentsOfFile:[NSString stringWithUTF8LispString:file] + byReference:YES]; + } + else if (STRINGP (data)) + sound = [[NSSound alloc] + initWithData:[NSData dataWithBytes:(SDATA (data)) + length:(SBYTES (data))]]; + else + sound = nil; + + return CF_BRIDGING_RETAIN (MRC_AUTORELEASE (sound)); + } + + void + mac_sound_play (CFTypeRef mac_sound, Lisp_Object volume, Lisp_Object device) + { + NSSound *sound = (__bridge NSSound *) mac_sound; + + if ((INTEGERP (volume) || FLOATP (volume)) + && [sound respondsToSelector:@selector(setVolume:)]) + [sound setVolume:(INTEGERP (volume) ? XFASTINT (volume) * 0.01 + : XFLOAT_DATA (volume))]; + if (STRINGP (device) + && [sound respondsToSelector:@selector(setPlaybackDeviceIdentifier:)]) + [sound setPlaybackDeviceIdentifier:[NSString stringWithLispString:device]]; + + [emacsController addAndPlaySound:sound]; + } === modified file 'src/sound.c' *** src/sound.c 2013-01-01 09:11:05 +0000 --- src/sound.c 2013-03-17 08:17:27 +0000 *************** *** 53,59 **** /* BEGIN: Non Windows Includes */ ! #ifndef WINDOWSNT #include <sys/ioctl.h> --- 53,59 ---- /* BEGIN: Non Windows Includes */ ! #if !defined WINDOWSNT && !defined HAVE_MACGUI #include <sys/ioctl.h> *************** *** 79,85 **** /* END: Non Windows Includes */ ! #else /* WINDOWSNT */ /* BEGIN: Windows Specific Includes */ #include <stdio.h> --- 79,85 ---- /* END: Non Windows Includes */ ! #elif defined WINDOWSNT /* BEGIN: Windows Specific Includes */ #include <stdio.h> *************** *** 88,94 **** #include <mmsystem.h> /* END: Windows Specific Includes */ ! #endif /* WINDOWSNT */ /* BEGIN: Common Definitions */ --- 88,97 ---- #include <mmsystem.h> /* END: Windows Specific Includes */ ! #else /* HAVE_MACGUI */ ! #include "blockinput.h" ! #include "macterm.h" ! #endif /* HAVE_MACGUI */ /* BEGIN: Common Definitions */ *************** *** 112,118 **** /* END: Common Definitions */ /* BEGIN: Non Windows Definitions */ ! #ifndef WINDOWSNT /* Structure forward declarations. */ --- 115,121 ---- /* END: Common Definitions */ /* BEGIN: Non Windows Definitions */ ! #if !defined WINDOWSNT && !defined HAVE_MACGUI /* Structure forward declarations. */ *************** *** 291,303 **** #endif /* END: Non Windows Definitions */ ! #else /* WINDOWSNT */ /* BEGIN: Windows Specific Definitions */ static int do_play_sound (const char *, unsigned long); /* END: Windows Specific Definitions */ ! #endif /* WINDOWSNT */ /*********************************************************************** --- 294,309 ---- #endif /* END: Non Windows Definitions */ ! #elif defined WINDOWSNT /* BEGIN: Windows Specific Definitions */ static int do_play_sound (const char *, unsigned long); /* END: Windows Specific Definitions */ ! #else /* HAVE_MACGUI */ ! extern CFTypeRef mac_sound_create (Lisp_Object, Lisp_Object); ! extern void mac_sound_play (CFTypeRef, Lisp_Object, Lisp_Object); ! #endif /* HAVE_MACGUI */ /*********************************************************************** *************** *** 428,434 **** /* END: Common functions */ /* BEGIN: Non Windows functions */ ! #ifndef WINDOWSNT /* Find out the type of the sound file whose file descriptor is FD. S is the sound file structure to fill in. */ --- 434,440 ---- /* END: Common functions */ /* BEGIN: Non Windows functions */ ! #if !defined WINDOWSNT && !defined HAVE_MACGUI /* Find out the type of the sound file whose file descriptor is FD. S is the sound file structure to fill in. */ *************** *** 1247,1253 **** /* END: Non Windows functions */ ! #else /* WINDOWSNT */ /* BEGIN: Windows specific functions */ --- 1253,1259 ---- /* END: Non Windows functions */ ! #elif defined WINDOWSNT /* BEGIN: Windows specific functions */ *************** *** 1356,1361 **** --- 1362,1370 ---- Lisp_Object file; struct gcpro gcpro1, gcpro2; Lisp_Object args[2]; + #ifdef HAVE_MACGUI + CFTypeRef mac_sound; + #endif #else /* WINDOWSNT */ int len = 0; Lisp_Object lo_file = {0}; *************** *** 1369,1375 **** if (!parse_sound (sound, attrs)) error ("Invalid sound specification"); ! #ifndef WINDOWSNT file = Qnil; GCPRO2 (sound, file); current_sound_device = xzalloc (sizeof *current_sound_device); --- 1378,1384 ---- if (!parse_sound (sound, attrs)) error ("Invalid sound specification"); ! #if !defined WINDOWSNT && !defined HAVE_MACGUI file = Qnil; GCPRO2 (sound, file); current_sound_device = xzalloc (sizeof *current_sound_device); *************** *** 1435,1441 **** /* Clean up. */ UNGCPRO; ! #else /* WINDOWSNT */ lo_file = Fexpand_file_name (attrs[SOUND_FILE], Qnil); len = XSTRING (lo_file)->size; --- 1444,1450 ---- /* Clean up. */ UNGCPRO; ! #elif defined WINDOWSNT lo_file = Fexpand_file_name (attrs[SOUND_FILE], Qnil); len = XSTRING (lo_file)->size; *************** *** 1464,1470 **** } i_result = do_play_sound (psz_file, ui_volume); ! #endif /* WINDOWSNT */ unbind_to (count, Qnil); return Qnil; --- 1473,1513 ---- } i_result = do_play_sound (psz_file, ui_volume); ! #else /* HAVE_MACGUI */ ! if (inhibit_window_system || noninteractive) ! error ("Sound support on Mac requires a window system"); ! ! file = Qnil; ! GCPRO2 (sound, file); ! ! if (STRINGP (attrs[SOUND_FILE])) ! { ! /* Open the sound file. */ ! int fd = openp (Fcons (Vdata_directory, Qnil), ! attrs[SOUND_FILE], Qnil, &file, Qnil); ! ! if (fd < 0) ! error ("Could not open sound file: %s", strerror (errno)); ! emacs_close (fd); ! } ! ! block_input (); ! mac_sound = mac_sound_create (file, attrs[SOUND_DATA]); ! unblock_input (); ! if (mac_sound == NULL) ! error ("Unknown sound format"); ! ! args[0] = Qplay_sound_functions; ! args[1] = sound; ! Frun_hook_with_args (2, args); ! ! block_input (); ! mac_sound_play (mac_sound, attrs[SOUND_VOLUME], attrs[SOUND_DEVICE]); ! CFRelease (mac_sound); ! unblock_input (); ! ! UNGCPRO; ! #endif /* HAVE_MACGUI */ unbind_to (count, Qnil); return Qnil;
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.