This source file includes following definitions.
- sound_perror
- sound_warning
- parse_sound
- string_default
- find_sound_type
- sound_cleanup
- le2hl
- le2hs
- be2hl
- wav_init
- wav_play
- au_init
- au_play
- vox_open
- vox_configure
- vox_close
- vox_choose_format
- vox_init
- vox_write
- alsa_sound_perror
- alsa_open
- alsa_period_size
- alsa_configure
- alsa_close
- alsa_choose_format
- alsa_write
- snd_error_quiet
- alsa_init
- do_play_sound
- DEFUN
- syms_of_sound
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <config.h>
40
41 #if defined HAVE_SOUND
42
43
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <sys/types.h>
47 #include <errno.h>
48
49 #include "lisp.h"
50 #include "atimer.h"
51 #include "syssignal.h"
52
53
54
55
56 #ifndef WINDOWSNT
57
58 #include <byteswap.h>
59
60 #include <sys/ioctl.h>
61
62
63
64
65 #ifdef HAVE_MACHINE_SOUNDCARD_H
66 #include <machine/soundcard.h>
67 #endif
68 #ifdef HAVE_SYS_SOUNDCARD_H
69 #include <sys/soundcard.h>
70 #endif
71 #ifdef HAVE_SOUNDCARD_H
72 #include <soundcard.h>
73 #endif
74 #ifdef HAVE_ALSA
75 #include <alsa/asoundlib.h>
76 #endif
77
78
79
80 #else
81
82
83 #include <stdio.h>
84 #include <limits.h>
85 #include <mbstring.h>
86 #include <windows.h>
87 #include <mmsystem.h>
88
89 #include "coding.h"
90 #include "w32common.h"
91 #include "w32.h"
92
93
94 #endif
95
96
97
98
99
100 enum sound_attr
101 {
102 SOUND_FILE,
103 SOUND_DATA,
104 SOUND_DEVICE,
105 SOUND_VOLUME,
106 SOUND_ATTR_SENTINEL
107 };
108
109
110
111
112 #ifndef WINDOWSNT
113
114
115
116 struct sound;
117 struct sound_device;
118
119
120
121
122 struct wav_header
123 {
124 u_int32_t magic;
125 u_int32_t length;
126 u_int32_t chunk_type;
127 u_int32_t chunk_format;
128 u_int32_t chunk_length;
129 u_int16_t format;
130 u_int16_t channels;
131 u_int32_t sample_rate;
132 u_int32_t bytes_per_second;
133 u_int16_t sample_size;
134 u_int16_t precision;
135 u_int32_t chunk_data;
136 u_int32_t data_length;
137 };
138
139
140
141
142 struct au_header
143 {
144
145 u_int32_t magic_number;
146
147
148 u_int32_t data_offset;
149
150
151 u_int32_t data_size;
152
153
154
155
156
157
158
159
160
161
162
163 u_int32_t encoding;
164
165
166 u_int32_t sample_rate;
167
168
169 u_int32_t channels;
170 };
171
172
173
174 #define MAX_SOUND_HEADER_BYTES \
175 max (sizeof (struct wav_header), sizeof (struct au_header))
176
177
178
179 struct sound_device
180 {
181
182 Lisp_Object file;
183
184
185 int fd;
186
187
188 int format;
189
190
191 int volume;
192
193
194 int sample_size;
195
196
197 int sample_rate;
198
199
200 int bps;
201
202
203 int channels;
204
205
206 void (* open) (struct sound_device *sd);
207
208
209 void (* close) (struct sound_device *sd);
210
211
212 void (* configure) (struct sound_device *device);
213
214
215 void (* choose_format) (struct sound_device *sd,
216 struct sound *s);
217
218
219
220 ptrdiff_t (* period_size) (struct sound_device *sd);
221
222
223 void (* write) (struct sound_device *sd, const char *buffer,
224 ptrdiff_t nbytes);
225
226
227 void *data;
228 };
229
230
231
232 enum sound_type
233 {
234 RIFF,
235 SUN_AUDIO
236 };
237
238
239
240 struct sound
241 {
242
243 enum sound_type type;
244
245
246 int fd;
247
248
249
250 char *header;
251
252
253
254 int header_size;
255
256
257 Lisp_Object data;
258
259
260 void (* play) (struct sound *s, struct sound_device *sd);
261 };
262
263
264
265
266 static struct sound_device *current_sound_device;
267 static struct sound *current_sound;
268
269
270
271 static void vox_write (struct sound_device *, const char *, ptrdiff_t);
272 static bool wav_init (struct sound *);
273 static void wav_play (struct sound *, struct sound_device *);
274 static bool au_init (struct sound *);
275 static void au_play (struct sound *, struct sound_device *);
276
277
278 #else
279
280
281 static int do_play_sound (const char *, unsigned long);
282
283
284 #endif
285
286
287
288
289
290
291
292
293 #ifndef WINDOWSNT
294
295
296 static AVOID
297 sound_perror (const char *msg)
298 {
299 int saved_errno = errno;
300
301 turn_on_atimers (1);
302 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
303 {
304 sigset_t unblocked;
305 sigemptyset (&unblocked);
306 #ifdef USABLE_SIGIO
307 sigaddset (&unblocked, SIGIO);
308 #else
309 sigaddset (&unblocked, SIGPOLL);
310 #endif
311 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
312 }
313 #endif
314 if (saved_errno != 0)
315 error ("%s: %s", msg, emacs_strerror (saved_errno));
316 else
317 error ("%s", msg);
318 }
319
320
321
322 static void
323 sound_warning (const char *msg)
324 {
325 message1 (msg);
326 }
327 #endif
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356 static bool
357 parse_sound (Lisp_Object sound, Lisp_Object *attrs)
358 {
359
360 if (!CONSP (sound) || !EQ (XCAR (sound), Qsound))
361 return 0;
362
363 sound = XCDR (sound);
364 attrs[SOUND_FILE] = plist_get (sound, QCfile);
365 attrs[SOUND_DATA] = plist_get (sound, QCdata);
366 attrs[SOUND_DEVICE] = plist_get (sound, QCdevice);
367 attrs[SOUND_VOLUME] = plist_get (sound, QCvolume);
368
369 #ifndef WINDOWSNT
370
371 if (!STRINGP (attrs[SOUND_FILE])
372 && !STRINGP (attrs[SOUND_DATA]))
373 return 0;
374 #else
375
376
377
378
379 if (!STRINGP (attrs[SOUND_FILE]))
380 {
381 return 0;
382 }
383 #endif
384
385
386 if (!NILP (attrs[SOUND_VOLUME]))
387 {
388 if (FIXNUMP (attrs[SOUND_VOLUME]))
389 {
390 EMACS_INT volume = XFIXNUM (attrs[SOUND_VOLUME]);
391 if (! (0 <= volume && volume <= 100))
392 return 0;
393 }
394 else if (FLOATP (attrs[SOUND_VOLUME]))
395 {
396 double volume = XFLOAT_DATA (attrs[SOUND_VOLUME]);
397 if (! (0 <= volume && volume <= 1))
398 return 0;
399 }
400 else
401 return 0;
402 }
403
404 #ifndef WINDOWSNT
405
406 if (!NILP (attrs[SOUND_DEVICE])
407 && !STRINGP (attrs[SOUND_DEVICE]))
408 return 0;
409 #endif
410
411
412
413
414 return 1;
415 }
416
417
418
419
420 #ifndef WINDOWSNT
421
422
423
424 static char const *
425 string_default (Lisp_Object s, char const *default_value)
426 {
427 return STRINGP (s) ? SSDATA (s) : default_value;
428 }
429
430
431
432
433
434 static void
435 find_sound_type (struct sound *s)
436 {
437 if (!wav_init (s) && !au_init (s))
438 error ("Unknown sound format");
439 }
440
441
442
443
444 static void
445 sound_cleanup (void)
446 {
447 if (current_sound_device->close)
448 current_sound_device->close (current_sound_device);
449 if (current_sound->fd > 0)
450 emacs_close (current_sound->fd);
451 xfree (current_sound_device);
452 xfree (current_sound);
453 }
454
455
456
457
458
459
460
461
462 static u_int32_t
463 le2hl (u_int32_t value)
464 {
465 #ifdef WORDS_BIGENDIAN
466 value = bswap_32 (value);
467 #endif
468 return value;
469 }
470
471
472
473
474
475 static u_int16_t
476 le2hs (u_int16_t value)
477 {
478 #ifdef WORDS_BIGENDIAN
479 value = bswap_16 (value);
480 #endif
481 return value;
482 }
483
484
485
486
487
488 static u_int32_t
489 be2hl (u_int32_t value)
490 {
491 #ifndef WORDS_BIGENDIAN
492 value = bswap_32 (value);
493 #endif
494 return value;
495 }
496
497
498
499
500
501
502
503
504
505
506
507 static bool
508 wav_init (struct sound *s)
509 {
510 struct wav_header *header = (struct wav_header *) s->header;
511
512 if (s->header_size < sizeof *header
513 || memcmp (s->header, "RIFF", 4) != 0)
514 return 0;
515
516
517
518 header->magic = le2hl (header->magic);
519 header->length = le2hl (header->length);
520 header->chunk_type = le2hl (header->chunk_type);
521 header->chunk_format = le2hl (header->chunk_format);
522 header->chunk_length = le2hl (header->chunk_length);
523 header->format = le2hs (header->format);
524 header->channels = le2hs (header->channels);
525 header->sample_rate = le2hl (header->sample_rate);
526 header->bytes_per_second = le2hl (header->bytes_per_second);
527 header->sample_size = le2hs (header->sample_size);
528 header->precision = le2hs (header->precision);
529 header->chunk_data = le2hl (header->chunk_data);
530 header->data_length = le2hl (header->data_length);
531
532
533 s->type = RIFF;
534 s->play = wav_play;
535
536 return 1;
537 }
538
539
540
541
542 static void
543 wav_play (struct sound *s, struct sound_device *sd)
544 {
545 struct wav_header *header = (struct wav_header *) s->header;
546
547
548
549 sd->choose_format (sd, s);
550
551
552 sd->sample_size = header->sample_size;
553 sd->sample_rate = header->sample_rate;
554 sd->bps = header->bytes_per_second;
555 sd->channels = header->channels;
556 sd->configure (sd);
557
558
559
560
561
562 if (STRINGP (s->data))
563 sd->write (sd, SSDATA (s->data) + sizeof *header,
564 SBYTES (s->data) - sizeof *header);
565 else
566 {
567 ptrdiff_t nbytes = 0;
568 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
569 ptrdiff_t data_left = header->data_length;
570 USE_SAFE_ALLOCA;
571 char *buffer = SAFE_ALLOCA (blksize);
572 lseek (s->fd, sizeof *header, SEEK_SET);
573 while (data_left > 0
574 && (nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
575 {
576
577 if (data_left < nbytes) nbytes = data_left;
578 data_left -= nbytes;
579 sd->write (sd, buffer, nbytes);
580 }
581
582 if (nbytes < 0)
583 sound_perror ("Error reading sound file");
584 SAFE_FREE ();
585 }
586 }
587
588
589
590
591
592
593
594
595 enum au_encoding
596 {
597 AU_ENCODING_ULAW_8 = 1,
598 AU_ENCODING_8,
599 AU_ENCODING_16,
600 AU_ENCODING_24,
601 AU_ENCODING_32,
602 AU_ENCODING_IEEE32,
603 AU_ENCODING_IEEE64,
604 AU_COMPRESSED = 23,
605 AU_ENCODING_ALAW_8 = 27
606 };
607
608
609
610
611
612
613
614
615 static bool
616 au_init (struct sound *s)
617 {
618 struct au_header *header = (struct au_header *) s->header;
619
620 if (s->header_size < sizeof *header
621 || memcmp (s->header, ".snd", 4) != 0)
622 return 0;
623
624 header->magic_number = be2hl (header->magic_number);
625 header->data_offset = be2hl (header->data_offset);
626 header->data_size = be2hl (header->data_size);
627 header->encoding = be2hl (header->encoding);
628 header->sample_rate = be2hl (header->sample_rate);
629 header->channels = be2hl (header->channels);
630
631
632 s->type = SUN_AUDIO;
633 s->play = au_play;
634
635 return 1;
636 }
637
638
639
640
641 static void
642 au_play (struct sound *s, struct sound_device *sd)
643 {
644 struct au_header *header = (struct au_header *) s->header;
645
646 sd->sample_size = 0;
647 sd->sample_rate = header->sample_rate;
648 sd->bps = 0;
649 sd->channels = header->channels;
650 sd->choose_format (sd, s);
651 sd->configure (sd);
652
653 if (STRINGP (s->data))
654 sd->write (sd, SSDATA (s->data) + header->data_offset,
655 SBYTES (s->data) - header->data_offset);
656 else
657 {
658 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
659 ptrdiff_t nbytes;
660
661
662 lseek (s->fd, header->data_offset, SEEK_SET);
663
664
665 USE_SAFE_ALLOCA;
666 char *buffer = SAFE_ALLOCA (blksize);
667 while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
668 sd->write (sd, buffer, nbytes);
669
670 if (nbytes < 0)
671 sound_perror ("Error reading sound file");
672 SAFE_FREE ();
673 }
674 }
675
676
677
678
679
680
681
682
683
684
685
686
687
688 static void
689 vox_open (struct sound_device *sd)
690 {
691
692 char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE);
693 sd->fd = emacs_open (file, O_WRONLY, 0);
694 if (sd->fd < 0)
695 sound_perror (file);
696 }
697
698
699
700
701 static void
702 vox_configure (struct sound_device *sd)
703 {
704 int val;
705 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
706 sigset_t oldset, blocked;
707 #endif
708
709 eassert (sd->fd >= 0);
710
711
712
713
714 turn_on_atimers (0);
715 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
716 sigemptyset (&blocked);
717 #ifdef USABLE_SIGIO
718 sigaddset (&blocked, SIGIO);
719 #else
720 sigaddset (&blocked, SIGPOLL);
721 #endif
722 pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
723 #endif
724
725 val = sd->format;
726 if (ioctl (sd->fd, SNDCTL_DSP_SETFMT, &sd->format) < 0
727 || val != sd->format)
728 sound_perror ("Could not set sound format");
729
730 val = sd->channels != 1;
731 if (ioctl (sd->fd, SNDCTL_DSP_STEREO, &val) < 0
732 || val != (sd->channels != 1))
733 sound_perror ("Could not set stereo/mono");
734
735
736
737 if (sd->sample_rate > 0)
738 {
739 val = sd->sample_rate;
740 if (ioctl (sd->fd, SNDCTL_DSP_SPEED, &sd->sample_rate) < 0)
741 sound_perror ("Could not set sound speed");
742 else if (val != sd->sample_rate)
743 sound_warning ("Could not set sample rate");
744 }
745
746 if (sd->volume > 0)
747 {
748 int volume = sd->volume & 0xff;
749 volume |= volume << 8;
750
751 ioctl (sd->fd, SOUND_MIXER_WRITE_PCM, &volume);
752 }
753
754 turn_on_atimers (1);
755 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
756 pthread_sigmask (SIG_SETMASK, &oldset, 0);
757 #endif
758 }
759
760
761
762
763 static void
764 vox_close (struct sound_device *sd)
765 {
766 if (sd->fd >= 0)
767 {
768
769
770
771 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
772 sigset_t blocked, oldset;
773 sigemptyset (&blocked);
774 #ifdef USABLE_SIGIO
775 sigaddset (&blocked, SIGIO);
776 #else
777 sigaddset (&blocked, SIGPOLL);
778 #endif
779 pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
780 #endif
781 turn_on_atimers (0);
782
783
784 ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
785
786 turn_on_atimers (1);
787 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
788 pthread_sigmask (SIG_SETMASK, &oldset, 0);
789 #endif
790
791
792 emacs_close (sd->fd);
793 sd->fd = -1;
794 }
795 }
796
797
798
799
800 static void
801 vox_choose_format (struct sound_device *sd, struct sound *s)
802 {
803 if (s->type == RIFF)
804 {
805 struct wav_header *h = (struct wav_header *) s->header;
806 if (h->precision == 8)
807 sd->format = AFMT_U8;
808 else if (h->precision == 16)
809 sd->format = AFMT_S16_LE;
810 else
811 error ("Unsupported WAV file format");
812 }
813 else if (s->type == SUN_AUDIO)
814 {
815 struct au_header *header = (struct au_header *) s->header;
816 switch (header->encoding)
817 {
818 case AU_ENCODING_ULAW_8:
819 case AU_ENCODING_IEEE32:
820 case AU_ENCODING_IEEE64:
821 sd->format = AFMT_MU_LAW;
822 break;
823
824 case AU_ENCODING_8:
825 case AU_ENCODING_16:
826 case AU_ENCODING_24:
827 case AU_ENCODING_32:
828 sd->format = AFMT_S16_LE;
829 break;
830
831 default:
832 error ("Unsupported AU file format");
833 }
834 }
835 else
836 emacs_abort ();
837 }
838
839
840
841
842
843 static bool
844 vox_init (struct sound_device *sd)
845 {
846
847 char const *file = string_default (sd->file, DEFAULT_SOUND_DEVICE);
848 int fd = emacs_open (file, O_WRONLY, 0);
849 if (fd >= 0)
850 emacs_close (fd);
851 else
852 return 0;
853
854 sd->fd = -1;
855 sd->open = vox_open;
856 sd->close = vox_close;
857 sd->configure = vox_configure;
858 sd->choose_format = vox_choose_format;
859 sd->write = vox_write;
860 sd->period_size = NULL;
861
862 return 1;
863 }
864
865
866
867 static void
868 vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
869 {
870 if (emacs_write_sig (sd->fd, buffer, nbytes) != nbytes)
871 sound_perror ("Error writing to sound device");
872 }
873
874 #ifdef HAVE_ALSA
875
876
877
878
879
880
881 #ifndef DEFAULT_ALSA_SOUND_DEVICE
882 #define DEFAULT_ALSA_SOUND_DEVICE "default"
883 #endif
884
885 static AVOID
886 alsa_sound_perror (const char *msg, int err)
887 {
888 error ("%s: %s", msg, snd_strerror (err));
889 }
890
891 struct alsa_params
892 {
893 snd_pcm_t *handle;
894 snd_pcm_hw_params_t *hwparams;
895 snd_pcm_sw_params_t *swparams;
896 snd_pcm_uframes_t period_size;
897 };
898
899
900
901
902 static void
903 alsa_open (struct sound_device *sd)
904 {
905
906 struct alsa_params *p = xmalloc (sizeof *p);
907 char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE);
908 int err;
909
910 p->handle = NULL;
911 p->hwparams = NULL;
912 p->swparams = NULL;
913
914 sd->fd = -1;
915 sd->data = p;
916
917
918 err = snd_pcm_open (&p->handle, file, SND_PCM_STREAM_PLAYBACK, 0);
919 if (err < 0)
920 alsa_sound_perror (file, err);
921 }
922
923 static ptrdiff_t
924 alsa_period_size (struct sound_device *sd)
925 {
926 struct alsa_params *p = (struct alsa_params *) sd->data;
927 int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
928 return p->period_size * (fact > 0 ? fact : 1);
929 }
930
931 static void
932 alsa_configure (struct sound_device *sd)
933 {
934 int val, err, dir;
935 unsigned uval;
936 struct alsa_params *p = (struct alsa_params *) sd->data;
937 snd_pcm_uframes_t buffer_size;
938
939 eassert (p->handle != 0);
940
941 err = snd_pcm_hw_params_malloc (&p->hwparams);
942 if (err < 0)
943 alsa_sound_perror ("Could not allocate hardware parameter structure", err);
944
945 err = snd_pcm_sw_params_malloc (&p->swparams);
946 if (err < 0)
947 alsa_sound_perror ("Could not allocate software parameter structure", err);
948
949 err = snd_pcm_hw_params_any (p->handle, p->hwparams);
950 if (err < 0)
951 alsa_sound_perror ("Could not initialize hardware parameter structure", err);
952
953 err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
954 SND_PCM_ACCESS_RW_INTERLEAVED);
955 if (err < 0)
956 alsa_sound_perror ("Could not set access type", err);
957
958 val = sd->format;
959 err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val);
960 if (err < 0)
961 alsa_sound_perror ("Could not set sound format", err);
962
963 uval = sd->sample_rate;
964 err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &uval, 0);
965 if (err < 0)
966 alsa_sound_perror ("Could not set sample rate", err);
967
968 val = sd->channels;
969 err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val);
970 if (err < 0)
971 alsa_sound_perror ("Could not set channel count", err);
972
973 err = snd_pcm_hw_params (p->handle, p->hwparams);
974 if (err < 0)
975 alsa_sound_perror ("Could not set parameters", err);
976
977
978 err = snd_pcm_hw_params_get_period_size (p->hwparams, &p->period_size, &dir);
979 if (err < 0)
980 alsa_sound_perror ("Unable to get period size for playback", err);
981
982 err = snd_pcm_hw_params_get_buffer_size (p->hwparams, &buffer_size);
983 if (err < 0)
984 alsa_sound_perror ("Unable to get buffer size for playback", err);
985
986 err = snd_pcm_sw_params_current (p->handle, p->swparams);
987 if (err < 0)
988 alsa_sound_perror ("Unable to determine current swparams for playback",
989 err);
990
991
992 err = snd_pcm_sw_params_set_start_threshold (p->handle, p->swparams,
993 (buffer_size / p->period_size)
994 * p->period_size);
995 if (err < 0)
996 alsa_sound_perror ("Unable to set start threshold mode for playback", err);
997
998
999 err = snd_pcm_sw_params_set_avail_min (p->handle, p->swparams, p->period_size);
1000 if (err < 0)
1001 alsa_sound_perror ("Unable to set avail min for playback", err);
1002
1003 err = snd_pcm_sw_params (p->handle, p->swparams);
1004 if (err < 0)
1005 alsa_sound_perror ("Unable to set sw params for playback\n", err);
1006
1007 snd_pcm_hw_params_free (p->hwparams);
1008 p->hwparams = NULL;
1009 snd_pcm_sw_params_free (p->swparams);
1010 p->swparams = NULL;
1011
1012 err = snd_pcm_prepare (p->handle);
1013 if (err < 0)
1014 alsa_sound_perror ("Could not prepare audio interface for use", err);
1015
1016 if (sd->volume > 0)
1017 {
1018 int chn;
1019 snd_mixer_t *handle;
1020 snd_mixer_elem_t *e;
1021 if (snd_mixer_open (&handle, 0) >= 0)
1022 {
1023 char const *file = string_default (sd->file,
1024 DEFAULT_ALSA_SOUND_DEVICE);
1025 if (snd_mixer_attach (handle, file) >= 0
1026 && snd_mixer_load (handle) >= 0
1027 && snd_mixer_selem_register (handle, NULL, NULL) >= 0)
1028 for (e = snd_mixer_first_elem (handle);
1029 e;
1030 e = snd_mixer_elem_next (e))
1031 {
1032 if (snd_mixer_selem_has_playback_volume (e))
1033 {
1034 long pmin, pmax, vol;
1035 snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax);
1036 vol = pmin + (sd->volume * (pmax - pmin)) / 100;
1037
1038 for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++)
1039 snd_mixer_selem_set_playback_volume (e, chn, vol);
1040 }
1041 }
1042 snd_mixer_close (handle);
1043 }
1044 }
1045 }
1046
1047
1048
1049
1050 static void
1051 alsa_close (struct sound_device *sd)
1052 {
1053 struct alsa_params *p = (struct alsa_params *) sd->data;
1054 if (p)
1055 {
1056 if (p->hwparams)
1057 snd_pcm_hw_params_free (p->hwparams);
1058 if (p->swparams)
1059 snd_pcm_sw_params_free (p->swparams);
1060 if (p->handle)
1061 {
1062 snd_pcm_drain (p->handle);
1063 snd_pcm_close (p->handle);
1064 }
1065 xfree (p);
1066 }
1067 }
1068
1069
1070
1071 static void
1072 alsa_choose_format (struct sound_device *sd, struct sound *s)
1073 {
1074 if (s->type == RIFF)
1075 {
1076 struct wav_header *h = (struct wav_header *) s->header;
1077 if (h->precision == 8)
1078 sd->format = SND_PCM_FORMAT_U8;
1079 else if (h->precision == 16)
1080 sd->format = SND_PCM_FORMAT_S16_LE;
1081 else
1082 error ("Unsupported WAV file format");
1083 }
1084 else if (s->type == SUN_AUDIO)
1085 {
1086 struct au_header *header = (struct au_header *) s->header;
1087 switch (header->encoding)
1088 {
1089 case AU_ENCODING_ULAW_8:
1090 sd->format = SND_PCM_FORMAT_MU_LAW;
1091 break;
1092 case AU_ENCODING_ALAW_8:
1093 sd->format = SND_PCM_FORMAT_A_LAW;
1094 break;
1095 case AU_ENCODING_IEEE32:
1096 sd->format = SND_PCM_FORMAT_FLOAT_BE;
1097 break;
1098 case AU_ENCODING_IEEE64:
1099 sd->format = SND_PCM_FORMAT_FLOAT64_BE;
1100 break;
1101 case AU_ENCODING_8:
1102 sd->format = SND_PCM_FORMAT_S8;
1103 break;
1104 case AU_ENCODING_16:
1105 sd->format = SND_PCM_FORMAT_S16_BE;
1106 break;
1107 case AU_ENCODING_24:
1108 sd->format = SND_PCM_FORMAT_S24_BE;
1109 break;
1110 case AU_ENCODING_32:
1111 sd->format = SND_PCM_FORMAT_S32_BE;
1112 break;
1113
1114 default:
1115 error ("Unsupported AU file format");
1116 }
1117 }
1118 else
1119 emacs_abort ();
1120 }
1121
1122
1123
1124
1125 static void
1126 alsa_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
1127 {
1128 struct alsa_params *p = (struct alsa_params *) sd->data;
1129
1130
1131 int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
1132 ptrdiff_t nwritten = 0;
1133 int err;
1134
1135 while (nwritten < nbytes)
1136 {
1137 snd_pcm_uframes_t frames = (nbytes - nwritten)/fact;
1138 if (frames == 0) break;
1139
1140 err = snd_pcm_writei (p->handle, buffer + nwritten, frames);
1141 if (err < 0)
1142 {
1143 if (err == -EPIPE)
1144 {
1145 err = snd_pcm_prepare (p->handle);
1146 if (err < 0)
1147 alsa_sound_perror ("Can't recover from underrun, prepare failed",
1148 err);
1149 }
1150 #ifdef ESTRPIPE
1151 else if (err == -ESTRPIPE)
1152 {
1153 while ((err = snd_pcm_resume (p->handle)) == -EAGAIN)
1154 sleep (1);
1155 if (err < 0)
1156 {
1157 err = snd_pcm_prepare (p->handle);
1158 if (err < 0)
1159 alsa_sound_perror ("Can't recover from suspend, "
1160 "prepare failed",
1161 err);
1162 }
1163 }
1164 #endif
1165 else
1166 alsa_sound_perror ("Error writing to sound device", err);
1167
1168 }
1169 else
1170 nwritten += err * fact;
1171 }
1172 }
1173
1174 static void
1175 snd_error_quiet (const char *file, int line, const char *function, int err,
1176 const char *fmt)
1177 {
1178 }
1179
1180
1181
1182
1183 static bool
1184 alsa_init (struct sound_device *sd)
1185 {
1186
1187 char const *file = string_default (sd->file, DEFAULT_ALSA_SOUND_DEVICE);
1188 snd_pcm_t *handle;
1189 int err;
1190
1191 snd_lib_error_set_handler ((snd_lib_error_handler_t) snd_error_quiet);
1192 err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0);
1193 snd_lib_error_set_handler (NULL);
1194 if (err < 0)
1195 return 0;
1196 snd_pcm_close (handle);
1197
1198 sd->fd = -1;
1199 sd->open = alsa_open;
1200 sd->close = alsa_close;
1201 sd->configure = alsa_configure;
1202 sd->choose_format = alsa_choose_format;
1203 sd->write = alsa_write;
1204 sd->period_size = alsa_period_size;
1205
1206 return 1;
1207 }
1208
1209 #endif
1210
1211
1212
1213 #else
1214
1215
1216
1217 #define SOUND_WARNING(func, error, text) \
1218 do { \
1219 char buf[1024]; \
1220 char err_string[MAXERRORLENGTH]; \
1221 func (error, err_string, sizeof (err_string)); \
1222 _snprintf (buf, sizeof (buf), "%s\nMCI Error: %s", \
1223 text, err_string); \
1224 message_with_string ("%s", build_string (buf), 1); \
1225 } while (0)
1226
1227 static int
1228 do_play_sound (const char *psz_file, unsigned long ui_volume)
1229 {
1230 int i_result = 0;
1231 MCIERROR mci_error = 0;
1232 char sz_cmd_buf_a[520];
1233 char sz_ret_buf_a[520];
1234 MMRESULT mm_result = MMSYSERR_NOERROR;
1235 unsigned long ui_volume_org = 0;
1236 BOOL b_reset_volume = FALSE;
1237 char warn_text[560];
1238
1239
1240
1241
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
1249
1250
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
1281
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 {
1299 mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org);
1300 if (mm_result == MMSYSERR_NOERROR)
1301 {
1302 b_reset_volume = TRUE;
1303 mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume);
1304 if (mm_result != MMSYSERR_NOERROR)
1305 {
1306 SOUND_WARNING (waveOutGetErrorText, mm_result,
1307 "waveOutSetVolume: failed to set the volume level"
1308 " of the WAVE_MAPPER device.\n"
1309 "As a result, the user selected volume level will"
1310 " not be used.");
1311 }
1312 }
1313 else
1314 {
1315 SOUND_WARNING (waveOutGetErrorText, mm_result,
1316 "waveOutGetVolume: failed to obtain the original"
1317 " volume level of the WAVE_MAPPER device.\n"
1318 "As a result, the user selected volume level will"
1319 " not be used.");
1320 }
1321 }
1322 memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
1323 memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
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 {
1329 strcpy (warn_text,
1330 "mciSendString: 'play' command failed to play sound file ");
1331 strcat (warn_text, psz_file);
1332 SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
1333 i_result = (int) mci_error;
1334 }
1335 memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
1336 memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
1337 strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
1338 mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
1339 NULL);
1340 if (b_reset_volume == TRUE)
1341 {
1342 mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org);
1343 if (mm_result != MMSYSERR_NOERROR)
1344 {
1345 SOUND_WARNING (waveOutGetErrorText, mm_result,
1346 "waveOutSetVolume: failed to reset the original"
1347 " volume level of the WAVE_MAPPER device.");
1348 }
1349 }
1350 return i_result;
1351 }
1352
1353
1354
1355 #endif
1356
1357 DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1, 0,
1358 doc:
1359
1360 )
1361 (Lisp_Object sound)
1362 {
1363 Lisp_Object attrs[SOUND_ATTR_SENTINEL];
1364 specpdl_ref count = SPECPDL_INDEX ();
1365
1366 #ifdef WINDOWSNT
1367 unsigned long ui_volume_tmp = UINT_MAX;
1368 unsigned long ui_volume = UINT_MAX;
1369 #endif
1370
1371
1372 if (!parse_sound (sound, attrs))
1373 error ("Invalid sound specification");
1374
1375 Lisp_Object file = Qnil;
1376
1377 #ifndef WINDOWSNT
1378 current_sound_device = xzalloc (sizeof *current_sound_device);
1379 current_sound = xzalloc (sizeof *current_sound);
1380 record_unwind_protect_void (sound_cleanup);
1381 char headerbuf[MAX_SOUND_HEADER_BYTES];
1382 current_sound->header = headerbuf;
1383
1384 if (STRINGP (attrs[SOUND_FILE]))
1385 {
1386
1387 current_sound->fd =
1388 openp (list1 (Vdata_directory), attrs[SOUND_FILE], Qnil, &file, Qnil,
1389 false, false, NULL);
1390 if (current_sound->fd < 0)
1391 sound_perror ("Could not open sound file");
1392
1393
1394 current_sound->header_size
1395 = emacs_read (current_sound->fd, current_sound->header,
1396 MAX_SOUND_HEADER_BYTES);
1397 if (current_sound->header_size < 0)
1398 sound_perror ("Invalid sound file header");
1399 }
1400 else
1401 {
1402 current_sound->data = attrs[SOUND_DATA];
1403 current_sound->header_size = min (MAX_SOUND_HEADER_BYTES, SBYTES (current_sound->data));
1404 memcpy (current_sound->header, SDATA (current_sound->data),
1405 current_sound->header_size);
1406 }
1407
1408
1409 find_sound_type (current_sound);
1410
1411
1412 current_sound_device->file = attrs[SOUND_DEVICE];
1413
1414 if (FIXNUMP (attrs[SOUND_VOLUME]))
1415 current_sound_device->volume = XFIXNAT (attrs[SOUND_VOLUME]);
1416 else if (FLOATP (attrs[SOUND_VOLUME]))
1417 current_sound_device->volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
1418
1419 CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);
1420
1421 #ifdef HAVE_ALSA
1422 if (!alsa_init (current_sound_device))
1423 #endif
1424 if (!vox_init (current_sound_device))
1425 error ("No usable sound device driver found");
1426
1427
1428 current_sound_device->open (current_sound_device);
1429
1430
1431 current_sound->play (current_sound, current_sound_device);
1432
1433 #else
1434
1435 file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
1436 file = ENCODE_FILE (file);
1437 if (FIXNUMP (attrs[SOUND_VOLUME]))
1438 {
1439 ui_volume_tmp = XFIXNAT (attrs[SOUND_VOLUME]);
1440 }
1441 else if (FLOATP (attrs[SOUND_VOLUME]))
1442 {
1443 ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
1444 }
1445
1446 CALLN (Frun_hook_with_args, Qplay_sound_functions, sound);
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457 if ((ui_volume_tmp > 0) && (ui_volume_tmp <= 100))
1458 {
1459 ui_volume = ui_volume_tmp * (UINT_MAX / 100);
1460 }
1461 (void)do_play_sound (SSDATA (file), ui_volume);
1462
1463 #endif
1464
1465 return unbind_to (count, Qnil);
1466 }
1467
1468
1469
1470
1471
1472 void
1473 syms_of_sound (void)
1474 {
1475 DEFSYM (QCdevice, ":device");
1476 DEFSYM (QCvolume, ":volume");
1477 DEFSYM (Qsound, "sound");
1478 DEFSYM (Qplay_sound_functions, "play-sound-functions");
1479
1480 defsubr (&Splay_sound_internal);
1481 }
1482
1483 #endif