comparison src/sound.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 11054d720c21
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
23 23
24 /* Originally written by Jamie Zawinski. 24 /* Originally written by Jamie Zawinski.
25 Hacked on quite a bit by various others. */ 25 Hacked on quite a bit by various others. */
26 26
27 #include <config.h> 27 #include <config.h>
28 #include <time.h>
29 #include "lisp.h" 28 #include "lisp.h"
30 29
31 #include "buffer.h" 30 #include "buffer.h"
32 #ifdef HAVE_X_WINDOWS 31 #ifdef HAVE_X_WINDOWS
33 #include "console-x.h" 32 #include "console-x.h"
35 34
36 #include "device.h" 35 #include "device.h"
37 #include "redisplay.h" 36 #include "redisplay.h"
38 #include "sysdep.h" 37 #include "sysdep.h"
39 38
40 #include "sysfile.h" 39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
41 42
42 #ifdef HAVE_NATIVE_SOUND 43 #ifdef HAVE_NATIVE_SOUND
43 # include "sysproc.h" 44 # include <netdb.h>
44 # include "nativesound.h"
45 #endif
46
47 #ifdef HAVE_ESD_SOUND
48 extern int esd_play_sound_file (char *file, int vol);
49 extern int esd_play_sound_data (unsigned char *data, size_t length, int vol);
50 # define DEVICE_CONNECTED_TO_ESD_P(x) 1 /* FIXME: better check */
51 #endif 45 #endif
52 46
53 int bell_volume; 47 int bell_volume;
54 int bell_inhibit_time;
55 Lisp_Object Vsound_alist; 48 Lisp_Object Vsound_alist;
56 Lisp_Object Vsynchronous_sounds; 49 Lisp_Object Vsynchronous_sounds;
57 Lisp_Object Vnative_sound_only_on_console; 50 Lisp_Object Vnative_sound_only_on_console;
58 Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound; 51 Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound;
59 52
53 /* These are defined in the appropriate file (sunplay.c, sgiplay.c,
54 or hpplay.c). */
55
56 extern void play_sound_file (char *name, int volume);
57 extern void play_sound_data (unsigned char *data, int length, int volume);
60 58
61 #ifdef HAVE_NAS_SOUND 59 #ifdef HAVE_NAS_SOUND
62 extern int nas_play_sound_file (char *name, int volume); 60 extern int nas_play_sound_file (char *name, int volume);
63 extern int nas_play_sound_data (unsigned char *data, int length, int volume); 61 extern int nas_play_sound_data (unsigned char *data, int length, int volume);
64 extern int nas_wait_for_sounds (void); 62 extern int nas_wait_for_sounds (void);
77 */ 75 */
78 (file, volume, device)) 76 (file, volume, device))
79 { 77 {
80 /* This function can call lisp */ 78 /* This function can call lisp */
81 int vol; 79 int vol;
82 #if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND) \ 80 #if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND)
83 || defined (HAVE_ESD_SOUND)
84 struct device *d = decode_device (device); 81 struct device *d = decode_device (device);
85 #endif 82 #endif
86 struct gcpro gcpro1; 83 struct gcpro gcpro1;
87 84
88 CHECK_STRING (file); 85 CHECK_STRING (file);
118 #ifdef HAVE_NAS_SOUND 115 #ifdef HAVE_NAS_SOUND
119 if (DEVICE_CONNECTED_TO_NAS_P (d)) 116 if (DEVICE_CONNECTED_TO_NAS_P (d))
120 { 117 {
121 char *fileext; 118 char *fileext;
122 119
123 TO_EXTERNAL_FORMAT (LISP_STRING, file, 120 GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext);
124 C_STRING_ALLOCA, fileext,
125 Qfile_name);
126 /* #### NAS code should allow specification of a device. */ 121 /* #### NAS code should allow specification of a device. */
127 if (nas_play_sound_file (fileext, vol)) 122 if (nas_play_sound_file (fileext, vol))
128 return Qnil; 123 return Qnil;
129 } 124 }
130 #endif /* HAVE_NAS_SOUND */ 125 #endif /* HAVE_NAS_SOUND */
131 126
132 #ifdef HAVE_ESD_SOUND
133 if (DEVICE_CONNECTED_TO_ESD_P (d))
134 {
135 char *fileext;
136 int result;
137
138 TO_EXTERNAL_FORMAT (LISP_STRING, file,
139 C_STRING_ALLOCA, fileext,
140 Qfile_name);
141
142 /* #### ESD uses alarm(). But why should we also stop SIGIO? */
143 stop_interrupts ();
144 result = esd_play_sound_file (fileext, vol);
145 start_interrupts ();
146 if (result)
147 return Qnil;
148 }
149 #endif /* HAVE_ESD_SOUND */
150
151 #ifdef HAVE_NATIVE_SOUND 127 #ifdef HAVE_NATIVE_SOUND
152 if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) 128 if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d))
153 { 129 {
154 const char *fileext; 130 CONST char *fileext;
155 131
156 TO_EXTERNAL_FORMAT (LISP_STRING, file, 132 GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext);
157 C_STRING_ALLOCA, fileext,
158 Qfile_name);
159 /* The sound code doesn't like getting SIGIO interrupts. 133 /* The sound code doesn't like getting SIGIO interrupts.
160 Unix sucks! */ 134 Unix sucks! */
161 stop_interrupts (); 135 stop_interrupts ();
162 play_sound_file ((char *) fileext, vol); 136 play_sound_file ((char *) fileext, vol);
163 start_interrupts (); 137 start_interrupts ();
315 Else just beep. 289 Else just beep.
316 */ 290 */
317 #ifdef HAVE_NAS_SOUND 291 #ifdef HAVE_NAS_SOUND
318 if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound)) 292 if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound))
319 { 293 {
320 const Extbyte *soundext; 294 CONST Extbyte *soundext;
321 Extcount soundextlen; 295 Extcount soundextlen;
322 296
323 TO_EXTERNAL_FORMAT (LISP_STRING, sound, 297 GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen);
324 ALLOCA, (soundext, soundextlen),
325 Qbinary);
326 if (nas_play_sound_data ((unsigned char*)soundext, soundextlen, vol)) 298 if (nas_play_sound_data ((unsigned char*)soundext, soundextlen, vol))
327 return Qnil; 299 return Qnil;
328 } 300 }
329 #endif /* HAVE_NAS_SOUND */ 301 #endif /* HAVE_NAS_SOUND */
330
331 #ifdef HAVE_ESD_SOUND
332 if (DEVICE_CONNECTED_TO_ESD_P (d) && STRINGP (sound))
333 {
334 Extbyte *soundext;
335 Extcount soundextlen;
336 int succes;
337
338 TO_EXTERNAL_FORMAT (LISP_STRING, sound, ALLOCA, (soundext, soundextlen),
339 Qbinary);
340
341 /* #### ESD uses alarm(). But why should we also stop SIGIO? */
342 stop_interrupts ();
343 succes = esd_play_sound_data (soundext, soundextlen, vol);
344 start_interrupts ();
345 QUIT;
346 if(succes)
347 return Qnil;
348 }
349 #endif /* HAVE_ESD_SOUND */
350 302
351 #ifdef HAVE_NATIVE_SOUND 303 #ifdef HAVE_NATIVE_SOUND
352 if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) 304 if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d))
353 && STRINGP (sound)) 305 && STRINGP (sound))
354 { 306 {
355 const Extbyte *soundext; 307 CONST Extbyte *soundext;
356 Extcount soundextlen; 308 Extcount soundextlen;
357 int succes; 309
358 310 GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen);
359 TO_EXTERNAL_FORMAT (LISP_STRING, sound,
360 ALLOCA, (soundext, soundextlen),
361 Qbinary);
362 /* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */ 311 /* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */
363 stop_interrupts (); 312 stop_interrupts ();
364 succes = play_sound_data ((unsigned char*)soundext, soundextlen, vol); 313 play_sound_data ((unsigned char*)soundext, soundextlen, vol);
365 start_interrupts (); 314 start_interrupts ();
366 QUIT; 315 QUIT;
367 if (succes) 316 return Qnil;
368 return Qnil;
369 } 317 }
370 #endif /* HAVE_NATIVE_SOUND */ 318 #endif /* HAVE_NATIVE_SOUND */
371 319
372 DEVMETH (d, ring_bell, (d, vol, pit, dur)); 320 DEVMETH (d, ring_bell, (d, vol, pit, dur));
373 return Qnil; 321 return Qnil;
397 the third argument is the device to make it in (defaults to the selected 345 the third argument is the device to make it in (defaults to the selected
398 device). 346 device).
399 */ 347 */
400 (arg, sound, device)) 348 (arg, sound, device))
401 { 349 {
402 static time_t last_bell_time; 350 struct device *d = decode_device (device);
403 static struct device *last_bell_device;
404 time_t now;
405 struct device *d = decode_device (device);
406 351
407 XSETDEVICE (device, d); 352 XSETDEVICE (device, d);
408 now = time (0); 353
409 354 /* #### This is utterly disgusting, and is probably a remnant from
355 legacy code that used `ding'+`message' to signal error instead
356 calling `error'. As a result, there is no way to beep from Lisp
357 directly, without also invoking this aspect. Maybe we should
358 define a `ring-bell' function that simply beeps on the console,
359 which `ding' should invoke? --hniksic */
410 if (NILP (arg) && !NILP (Vexecuting_macro)) 360 if (NILP (arg) && !NILP (Vexecuting_macro))
411 /* Stop executing a keyboard macro. */ 361 /* Stop executing a keyboard macro. */
412 error ("Keyboard macro terminated by a command ringing the bell"); 362 error ("Keyboard macro terminated by a command ringing the bell");
413 363 else if (visible_bell && DEVMETH (d, flash, (d)))
414 if (d == last_bell_device && now-last_bell_time < bell_inhibit_time)
415 return Qnil;
416 else if (!NILP (Vvisible_bell) && DEVMETH (d, flash, (d)))
417 ; 364 ;
418 else 365 else
419 Fplay_sound (sound, Qnil, device); 366 Fplay_sound (sound, Qnil, device);
420 367
421 last_bell_time = now; 368 return Qnil;
422 last_bell_device = d;
423 return Qnil;
424 } 369 }
425 370
426 DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /* 371 DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /*
427 Wait for all sounds to finish playing on DEVICE. 372 Wait for all sounds to finish playing on DEVICE.
428 */ 373 */
454 #ifdef HAVE_NAS_SOUND 399 #ifdef HAVE_NAS_SOUND
455 400
456 static void 401 static void
457 init_nas_sound (struct device *d) 402 init_nas_sound (struct device *d)
458 { 403 {
404 char *error;
405
459 #ifdef HAVE_X_WINDOWS 406 #ifdef HAVE_X_WINDOWS
460 if (DEVICE_X_P (d)) 407 if (DEVICE_X_P (d))
461 { 408 {
462 char *err_message = nas_init_play (DEVICE_X_DISPLAY (d)); 409 error = nas_init_play (DEVICE_X_DISPLAY (d));
463 DEVICE_CONNECTED_TO_NAS_P (d) = !err_message; 410 DEVICE_CONNECTED_TO_NAS_P (d) = !error;
464 /* Print out the message? */ 411 /* Print out the message? */
465 } 412 }
466 #endif /* HAVE_X_WINDOWS */ 413 #endif /* HAVE_X_WINDOWS */
467 } 414 }
468 415
578 Fprovide (intern ("native-sound")); 525 Fprovide (intern ("native-sound"));
579 #endif 526 #endif
580 #ifdef HAVE_NAS_SOUND 527 #ifdef HAVE_NAS_SOUND
581 Fprovide (intern ("nas-sound")); 528 Fprovide (intern ("nas-sound"));
582 #endif 529 #endif
583 #ifdef HAVE_ESD_SOUND
584 Fprovide (intern ("esd-sound"));
585 #endif
586 530
587 DEFVAR_INT ("bell-volume", &bell_volume /* 531 DEFVAR_INT ("bell-volume", &bell_volume /*
588 *How loud to be, from 0 to 100. 532 *How loud to be, from 0 to 100.
589 */ ); 533 */ );
590 bell_volume = 50; 534 bell_volume = 50;
591
592 DEFVAR_INT ("bell-inhibit-time", &bell_inhibit_time /*
593 *Don't ring the bell on the same device more than once within this many seconds.
594 */ );
595 bell_inhibit_time = 0;
596 535
597 DEFVAR_LISP ("sound-alist", &Vsound_alist /* 536 DEFVAR_LISP ("sound-alist", &Vsound_alist /*
598 An alist associating names with sounds. 537 An alist associating names with sounds.
599 When `beep' or `ding' is called with one of the name symbols, the associated 538 When `beep' or `ding' is called with one of the name symbols, the associated
600 sound will be generated instead of the standard beep. 539 sound will be generated instead of the standard beep.
618 557
619 You should probably add things to this list by calling the function 558 You should probably add things to this list by calling the function
620 load-sound-file. 559 load-sound-file.
621 560
622 Caveats: 561 Caveats:
623 - XEmacs must be built with sound support for your system. Not all 562 - You can only play audio data if running on the console screen of a
624 systems support sound. 563 Sun SparcStation, SGI, or HP9000s700.
625 564
626 - The pitch, duration, and volume options are available everywhere, but 565 - The pitch, duration, and volume options are available everywhere, but
627 many X servers ignore the `pitch' option. 566 many X servers ignore the `pitch' option.
628 567
629 The following beep-types are used by emacs itself: 568 The following beep-types are used by emacs itself: