From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: YAMAMOTO Mitsuharu Newsgroups: gmane.emacs.bugs Subject: bug#3351: 23.0.93; OSX sound support Date: Mon, 18 Mar 2013 11:47:46 +0900 Organization: Faculty of Science, Chiba University Message-ID: References: <9abbd5730905220631w7256450dp41cc4f1e511ea6d0@mail.gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Trace: ger.gmane.org 1363574925 26211 80.91.229.3 (18 Mar 2013 02:48:45 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 18 Mar 2013 02:48:45 +0000 (UTC) Cc: Alex =?UTF-8?Q?Schr=C3=B6der?= , 3351@debbugs.gnu.org To: Leo Liu Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Mar 18 03:49:10 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UHQ8G-0005UR-IF for geb-bug-gnu-emacs@m.gmane.org; Mon, 18 Mar 2013 03:49:04 +0100 Original-Received: from localhost ([::1]:57237 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHQ7t-0006tH-Kc for geb-bug-gnu-emacs@m.gmane.org; Sun, 17 Mar 2013 22:48:41 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:38909) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHQ7o-0006sx-Ov for bug-gnu-emacs@gnu.org; Sun, 17 Mar 2013 22:48:38 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UHQ7j-0003Rv-Sr for bug-gnu-emacs@gnu.org; Sun, 17 Mar 2013 22:48:36 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:56406) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHQ7j-0003Rh-MU for bug-gnu-emacs@gnu.org; Sun, 17 Mar 2013 22:48:31 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1UHQ9C-0005ZO-GM for bug-gnu-emacs@gnu.org; Sun, 17 Mar 2013 22:50:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: YAMAMOTO Mitsuharu Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 18 Mar 2013 02:50:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 3351 X-GNU-PR-Package: emacs,ns X-GNU-PR-Keywords: Original-Received: via spool by 3351-submit@debbugs.gnu.org id=B3351.136357497021360 (code B ref 3351); Mon, 18 Mar 2013 02:50:02 +0000 Original-Received: (at 3351) by debbugs.gnu.org; 18 Mar 2013 02:49:30 +0000 Original-Received: from localhost ([127.0.0.1]:60515 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UHQ8f-0005YT-9V for submit@debbugs.gnu.org; Sun, 17 Mar 2013 22:49:30 -0400 Original-Received: from mathmail.math.s.chiba-u.ac.jp ([133.82.132.2]:55099) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UHQ8Y-0005YD-B3 for 3351@debbugs.gnu.org; Sun, 17 Mar 2013 22:49:27 -0400 Original-Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id 3D271C055D; Mon, 18 Mar 2013 11:47:46 +0900 (JST) In-Reply-To: User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (=?UTF-8?Q?Shij=C5=8D?=) APEL/10.6 Emacs/22.3 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:72656 Archived-At: >>>>> On Sun, 17 Mar 2013 17:36:31 +0900, YAMAMOTO Mitsuharu said: >> 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 Oops, I didn't realize that play-sound-internal was supposed to be synchronous and unquittable. Below is an updated one. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp === modified file 'configure.ac' *** configure.ac 2013-03-11 03:49:04 +0000 --- configure.ac 2013-03-18 02:36:18 +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-18 02:36:18 +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 *************** *** 691,696 **** --- 692,700 ---- #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */ + @interface EmacsController (Sound) + @end + /* Some methods that are not declared in older versions. Should be used with some runtime check such as `respondsToSelector:'. */ *************** *** 868,870 **** --- 872,881 ---- @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-18 02:36:41 +0000 *************** *** 12207,12209 **** --- 12207,12263 ---- return result; } + + + /*********************************************************************** + Sound + ***********************************************************************/ + @implementation EmacsController (Sound) + + - (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finishedPlaying + { + [NSApp postDummyEvent]; + } + + @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]]; + + [sound setDelegate:emacsController]; + [sound play]; + while ([sound isPlaying]) + mac_run_loop_run_once (kEventDurationForever); + } === modified file 'src/macterm.h' *** src/macterm.h 2013-02-09 07:26:28 +0000 --- src/macterm.h 2013-03-18 02:36:18 +0000 *************** *** 652,657 **** --- 652,660 ---- extern void mac_invalidate_frame_cursor_rects (struct frame *f); extern int mac_webkit_supports_svg_p (void); + extern CFTypeRef mac_sound_create (Lisp_Object, Lisp_Object); + extern void mac_sound_play (CFTypeRef, Lisp_Object, Lisp_Object); + #define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc) \ CGContextSetFillColorWithColor (context, (gc)->cg_fore_color) #define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc) \ === modified file 'src/sound.c' *** src/sound.c 2013-01-01 09:11:05 +0000 --- src/sound.c 2013-03-18 02:36:18 +0000 *************** *** 53,59 **** /* BEGIN: Non Windows Includes */ ! #ifndef WINDOWSNT #include --- 53,59 ---- /* BEGIN: Non Windows Includes */ ! #if !defined WINDOWSNT && !defined HAVE_MACGUI #include *************** *** 79,85 **** /* END: Non Windows Includes */ ! #else /* WINDOWSNT */ /* BEGIN: Windows Specific Includes */ #include --- 79,85 ---- /* END: Non Windows Includes */ ! #elif defined WINDOWSNT /* BEGIN: Windows Specific Includes */ #include *************** *** 88,94 **** #include /* END: Windows Specific Includes */ ! #endif /* WINDOWSNT */ /* BEGIN: Common Definitions */ --- 88,97 ---- #include /* 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,297 **** #endif /* END: Non Windows Definitions */ ! #else /* WINDOWSNT */ /* BEGIN: Windows Specific Definitions */ static int do_play_sound (const char *, unsigned long); --- 294,300 ---- #endif /* END: Non Windows Definitions */ ! #elif defined WINDOWSNT /* BEGIN: Windows Specific Definitions */ static int do_play_sound (const char *, unsigned long); *************** *** 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. */ --- 431,437 ---- /* 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 */ --- 1250,1256 ---- /* END: Non Windows functions */ ! #elif defined WINDOWSNT /* BEGIN: Windows specific functions */ *************** *** 1356,1361 **** --- 1359,1367 ---- 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); --- 1375,1381 ---- 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; --- 1441,1447 ---- /* 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; --- 1470,1515 ---- } 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) ! { ! if (errno == 0) ! error ("Could not open sound file"); ! else ! 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;