(defgroup ispell): Arrange that definition starts at beginning of
[bpt/emacs.git] / src / sound.c
CommitLineData
7840ced1 1/* sound.c -- sound support.
53fab6e2 2 Copyright (C) 1998, 1999, 2001 Free Software Foundation.
7840ced1
GM
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21/* Written by Gerd Moellmann <gerd@gnu.org>. Tested with Luigi's
22 driver on FreeBSD 2.2.7 with a SoundBlaster 16. */
23
24#include <config.h>
25
26#if defined HAVE_SOUND
27
7840ced1
GM
28#include <fcntl.h>
29#include <unistd.h>
30#include <sys/types.h>
7840ced1 31#include <errno.h>
53fab6e2
GM
32#include "lisp.h"
33#include "dispextern.h"
34#include "atimer.h"
bb6e8cee
GM
35#include <signal.h>
36#include "syssignal.h"
7840ced1 37
502150e5
PJ
38#ifndef MSDOS
39#include <sys/ioctl.h>
40#endif
41
7840ced1
GM
42/* FreeBSD has machine/soundcard.h. Voxware sound driver docs mention
43 sys/soundcard.h. So, let's try whatever's there. */
44
45#ifdef HAVE_MACHINE_SOUNDCARD_H
46#include <machine/soundcard.h>
47#endif
48#ifdef HAVE_SYS_SOUNDCARD_H
49#include <sys/soundcard.h>
50#endif
80fcd514 51#ifdef HAVE_SOUNDCARD_H
80fcd514
KR
52#include <soundcard.h>
53#endif
54
55#ifndef DEFAULT_SOUND_DEVICE
56#define DEFAULT_SOUND_DEVICE "/dev/dsp"
57#endif
7840ced1 58
7840ced1
GM
59#define abs(X) ((X) < 0 ? -(X) : (X))
60
61/* Structure forward declarations. */
62
d1299cde 63struct sound;
7840ced1
GM
64struct sound_device;
65
66/* The file header of RIFF-WAVE files (*.wav). Files are always in
67 little-endian byte-order. */
68
69struct wav_header
70{
71 u_int32_t magic;
72 u_int32_t length;
73 u_int32_t chunk_type;
74 u_int32_t chunk_format;
75 u_int32_t chunk_length;
76 u_int16_t format;
77 u_int16_t channels;
78 u_int32_t sample_rate;
79 u_int32_t bytes_per_second;
80 u_int16_t sample_size;
81 u_int16_t precision;
82 u_int32_t chunk_data;
83 u_int32_t data_length;
84};
85
86/* The file header of Sun adio files (*.au). Files are always in
87 big-endian byte-order. */
88
89struct au_header
90{
91 /* ASCII ".snd" */
92 u_int32_t magic_number;
a4ff5d67 93
7840ced1
GM
94 /* Offset of data part from start of file. Minimum value is 24. */
95 u_int32_t data_offset;
a4ff5d67 96
7840ced1
GM
97 /* Size of data part, 0xffffffff if unknown. */
98 u_int32_t data_size;
99
100 /* Data encoding format.
101 1 8-bit ISDN u-law
102 2 8-bit linear PCM (REF-PCM)
103 3 16-bit linear PCM
104 4 24-bit linear PCM
105 5 32-bit linear PCM
106 6 32-bit IEEE floating-point
107 7 64-bit IEEE floating-point
108 23 8-bit u-law compressed using CCITT 0.721 ADPCM voice data
109 encoding scheme. */
110 u_int32_t encoding;
111
112 /* Number of samples per second. */
113 u_int32_t sample_rate;
114
115 /* Number of interleaved channels. */
116 u_int32_t channels;
117};
118
119/* Maximum of all sound file headers sizes. */
120
121#define MAX_SOUND_HEADER_BYTES \
122 max (sizeof (struct wav_header), sizeof (struct au_header))
123
124/* Interface structure for sound devices. */
125
126struct sound_device
127{
128 /* The name of the device or null meaning use a default device name. */
129 char *file;
130
131 /* File descriptor of the device. */
132 int fd;
133
134 /* Device-dependent format. */
135 int format;
136
137 /* Volume (0..100). Zero means unspecified. */
138 int volume;
139
140 /* Sample size. */
141 int sample_size;
142
143 /* Sample rate. */
144 int sample_rate;
145
146 /* Bytes per second. */
147 int bps;
148
149 /* 1 = mono, 2 = stereo, 0 = don't set. */
150 int channels;
a4ff5d67 151
7840ced1
GM
152 /* Open device SD. */
153 void (* open) P_ ((struct sound_device *sd));
154
155 /* Close device SD. */
156 void (* close) P_ ((struct sound_device *sd));
157
158 /* Configure SD accoring to device-dependent parameters. */
159 void (* configure) P_ ((struct sound_device *device));
a4ff5d67 160
d1299cde 161 /* Choose a device-dependent format for outputting sound S. */
7840ced1 162 void (* choose_format) P_ ((struct sound_device *sd,
d1299cde 163 struct sound *s));
7840ced1
GM
164
165 /* Write NYBTES bytes from BUFFER to device SD. */
dca0fc1c
KR
166 void (* write) P_ ((struct sound_device *sd, const char *buffer,
167 int nbytes));
7840ced1
GM
168
169 /* A place for devices to store additional data. */
170 void *data;
171};
172
173/* An enumerator for each supported sound file type. */
174
175enum sound_type
176{
177 RIFF,
178 SUN_AUDIO
179};
180
181/* Interface structure for sound files. */
182
d1299cde 183struct sound
7840ced1
GM
184{
185 /* The type of the file. */
186 enum sound_type type;
187
d1299cde 188 /* File descriptor of a sound file. */
7840ced1
GM
189 int fd;
190
d1299cde
GM
191 /* Pointer to sound file header. This contains header_size bytes
192 read from the start of a sound file. */
7840ced1
GM
193 char *header;
194
d1299cde
GM
195 /* Number of bytes raed from sound file. This is always <=
196 MAX_SOUND_HEADER_BYTES. */
197 int header_size;
198
199 /* Sound data, if a string. */
200 Lisp_Object data;
201
202 /* Play sound file S on device SD. */
a4ff5d67 203 void (* play) P_ ((struct sound *s, struct sound_device *sd));
7840ced1
GM
204};
205
206/* Indices of attributes in a sound attributes vector. */
207
208enum sound_attr
209{
210 SOUND_FILE,
d1299cde 211 SOUND_DATA,
7840ced1
GM
212 SOUND_DEVICE,
213 SOUND_VOLUME,
214 SOUND_ATTR_SENTINEL
215};
216
217/* Symbols. */
218
d1299cde 219extern Lisp_Object QCfile, QCdata;
7840ced1
GM
220Lisp_Object QCvolume, QCdevice;
221Lisp_Object Qsound;
2a53558d 222Lisp_Object Qplay_sound_functions;
7840ced1 223
14e415e7 224/* These are set during `play-sound-internal' so that sound_cleanup has
7840ced1
GM
225 access to them. */
226
d1299cde
GM
227struct sound_device *current_sound_device;
228struct sound *current_sound;
7840ced1
GM
229
230/* Function prototypes. */
231
232static void vox_open P_ ((struct sound_device *));
233static void vox_configure P_ ((struct sound_device *));
234static void vox_close P_ ((struct sound_device *sd));
d1299cde 235static void vox_choose_format P_ ((struct sound_device *, struct sound *));
7840ced1 236static void vox_init P_ ((struct sound_device *));
dca0fc1c 237static void vox_write P_ ((struct sound_device *, const char *, int));
7840ced1 238static void sound_perror P_ ((char *));
62725a92 239static void sound_warning P_ ((char *));
7840ced1 240static int parse_sound P_ ((Lisp_Object, Lisp_Object *));
d1299cde 241static void find_sound_type P_ ((struct sound *));
7840ced1
GM
242static u_int32_t le2hl P_ ((u_int32_t));
243static u_int16_t le2hs P_ ((u_int16_t));
244static u_int32_t be2hl P_ ((u_int32_t));
d1299cde
GM
245static int wav_init P_ ((struct sound *));
246static void wav_play P_ ((struct sound *, struct sound_device *));
247static int au_init P_ ((struct sound *));
248static void au_play P_ ((struct sound *, struct sound_device *));
7840ced1 249
9680b9d0
GM
250#if 0 /* Currently not used. */
251static u_int16_t be2hs P_ ((u_int16_t));
252#endif
253
7840ced1
GM
254
255\f
256/***********************************************************************
257 General
258 ***********************************************************************/
259
260/* Like perror, but signals an error. */
261
262static void
263sound_perror (msg)
264 char *msg;
265{
3297e2a1
AS
266 int saved_errno = errno;
267
62725a92
GM
268 turn_on_atimers (1);
269#ifdef SIGIO
270 sigunblock (sigmask (SIGIO));
271#endif
3297e2a1
AS
272 if (saved_errno != 0)
273 error ("%s: %s", msg, strerror (saved_errno));
62725a92
GM
274 else
275 error ("%s", msg);
276}
277
278
279/* Display a warning message. */
280
281static void
282sound_warning (msg)
283 char *msg;
284{
285 message (msg);
7840ced1
GM
286}
287
288
289/* Parse sound specification SOUND, and fill ATTRS with what is
290 found. Value is non-zero if SOUND Is a valid sound specification.
291 A valid sound specification is a list starting with the symbol
292 `sound'. The rest of the list is a property list which may
293 contain the following key/value pairs:
294
295 - `:file FILE'
296
297 FILE is the sound file to play. If it isn't an absolute name,
298 it's searched under `data-directory'.
299
d1299cde
GM
300 - `:data DATA'
301
302 DATA is a string containing sound data. Either :file or :data
303 may be present, but not both.
304
7840ced1
GM
305 - `:device DEVICE'
306
307 DEVICE is the name of the device to play on, e.g. "/dev/dsp2".
308 If not specified, a default device is used.
309
310 - `:volume VOL'
311
2a53558d
GM
312 VOL must be an integer in the range [0, 100], or a float in the
313 range [0, 1]. */
7840ced1
GM
314
315static int
316parse_sound (sound, attrs)
317 Lisp_Object sound;
318 Lisp_Object *attrs;
319{
320 /* SOUND must be a list starting with the symbol `sound'. */
321 if (!CONSP (sound) || !EQ (XCAR (sound), Qsound))
322 return 0;
323
324 sound = XCDR (sound);
325 attrs[SOUND_FILE] = Fplist_get (sound, QCfile);
d1299cde 326 attrs[SOUND_DATA] = Fplist_get (sound, QCdata);
7840ced1
GM
327 attrs[SOUND_DEVICE] = Fplist_get (sound, QCdevice);
328 attrs[SOUND_VOLUME] = Fplist_get (sound, QCvolume);
329
d1299cde
GM
330 /* File name or data must be specified. */
331 if (!STRINGP (attrs[SOUND_FILE])
332 && !STRINGP (attrs[SOUND_DATA]))
7840ced1
GM
333 return 0;
334
335 /* Volume must be in the range 0..100 or unspecified. */
336 if (!NILP (attrs[SOUND_VOLUME]))
337 {
2a53558d
GM
338 if (INTEGERP (attrs[SOUND_VOLUME]))
339 {
340 if (XINT (attrs[SOUND_VOLUME]) < 0
341 || XINT (attrs[SOUND_VOLUME]) > 100)
342 return 0;
343 }
344 else if (FLOATP (attrs[SOUND_VOLUME]))
345 {
346 if (XFLOAT_DATA (attrs[SOUND_VOLUME]) < 0
347 || XFLOAT_DATA (attrs[SOUND_VOLUME]) > 1)
348 return 0;
349 }
350 else
7840ced1
GM
351 return 0;
352 }
353
354 /* Device must be a string or unspecified. */
355 if (!NILP (attrs[SOUND_DEVICE])
356 && !STRINGP (attrs[SOUND_DEVICE]))
357 return 0;
358
359 return 1;
360}
361
362
363/* Find out the type of the sound file whose file descriptor is FD.
d1299cde 364 S is the sound file structure to fill in. */
7840ced1
GM
365
366static void
d1299cde
GM
367find_sound_type (s)
368 struct sound *s;
7840ced1 369{
d1299cde
GM
370 if (!wav_init (s) && !au_init (s))
371 error ("Unknown sound format");
7840ced1
GM
372}
373
374
14e415e7 375/* Function installed by play-sound-internal with record_unwind_protect. */
7840ced1
GM
376
377static Lisp_Object
378sound_cleanup (arg)
379 Lisp_Object arg;
380{
d1299cde 381 if (current_sound_device)
7840ced1 382 {
66e4690f
KR
383 if (current_sound_device->close)
384 current_sound_device->close (current_sound_device);
d1299cde
GM
385 if (current_sound->fd > 0)
386 emacs_close (current_sound->fd);
7840ced1 387 }
3887b449
GM
388
389 return Qnil;
7840ced1
GM
390}
391
392
14e415e7 393DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1, 0,
8c1a1077 394 doc: /* Play sound SOUND.
8c1a1077 395
14e415e7 396Internal use only, use `play-sound' instead. */)
8c1a1077 397 (sound)
7840ced1
GM
398 Lisp_Object sound;
399{
400 Lisp_Object attrs[SOUND_ATTR_SENTINEL];
7840ced1
GM
401 Lisp_Object file;
402 struct gcpro gcpro1, gcpro2;
7840ced1 403 struct sound_device sd;
d1299cde 404 struct sound s;
7840ced1 405 Lisp_Object args[2];
aed13378 406 int count = SPECPDL_INDEX ();
7840ced1
GM
407
408 file = Qnil;
409 GCPRO2 (sound, file);
410 bzero (&sd, sizeof sd);
d1299cde
GM
411 bzero (&s, sizeof s);
412 current_sound_device = &sd;
413 current_sound = &s;
7840ced1 414 record_unwind_protect (sound_cleanup, Qnil);
d1299cde 415 s.header = (char *) alloca (MAX_SOUND_HEADER_BYTES);
7840ced1
GM
416
417 /* Parse the sound specification. Give up if it is invalid. */
418 if (!parse_sound (sound, attrs))
d1299cde
GM
419 error ("Invalid sound specification");
420
421 if (STRINGP (attrs[SOUND_FILE]))
7840ced1 422 {
d1299cde
GM
423 /* Open the sound file. */
424 s.fd = openp (Fcons (Vdata_directory, Qnil),
3d05168a 425 attrs[SOUND_FILE], Qnil, &file, Qnil);
d1299cde 426 if (s.fd < 0)
62725a92 427 sound_perror ("Could not open sound file");
d1299cde
GM
428
429 /* Read the first bytes from the file. */
430 s.header_size = emacs_read (s.fd, s.header, MAX_SOUND_HEADER_BYTES);
431 if (s.header_size < 0)
62725a92 432 sound_perror ("Invalid sound file header");
d1299cde
GM
433 }
434 else
435 {
436 s.data = attrs[SOUND_DATA];
d5db4077
KR
437 s.header_size = min (MAX_SOUND_HEADER_BYTES, SBYTES (s.data));
438 bcopy (SDATA (s.data), s.header, s.header_size);
7840ced1
GM
439 }
440
d1299cde
GM
441 /* Find out the type of sound. Give up if we can't tell. */
442 find_sound_type (&s);
7840ced1
GM
443
444 /* Set up a device. */
445 if (STRINGP (attrs[SOUND_DEVICE]))
446 {
d5db4077 447 int len = SCHARS (attrs[SOUND_DEVICE]);
7840ced1 448 sd.file = (char *) alloca (len + 1);
d5db4077 449 strcpy (sd.file, SDATA (attrs[SOUND_DEVICE]));
7840ced1 450 }
a4ff5d67 451
7840ced1
GM
452 if (INTEGERP (attrs[SOUND_VOLUME]))
453 sd.volume = XFASTINT (attrs[SOUND_VOLUME]);
2a53558d
GM
454 else if (FLOATP (attrs[SOUND_VOLUME]))
455 sd.volume = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
7840ced1 456
2a53558d 457 args[0] = Qplay_sound_functions;
7840ced1 458 args[1] = sound;
52e386c2 459 Frun_hook_with_args (2, args);
7840ced1 460
d1299cde
GM
461 /* There is only one type of device we currently support, the VOX
462 sound driver. Set up the device interface functions for that
463 device. */
7840ced1 464 vox_init (&sd);
d1299cde
GM
465
466 /* Open the device. */
7840ced1
GM
467 sd.open (&sd);
468
d1299cde
GM
469 /* Play the sound. */
470 s.play (&s, &sd);
471
472 /* Close the input file, if any. */
473 if (!STRINGP (s.data))
474 {
475 emacs_close (s.fd);
476 s.fd = -1;
477 }
478
479 /* Close the device. */
7840ced1 480 sd.close (&sd);
d1299cde
GM
481
482 /* Clean up. */
483 current_sound_device = NULL;
484 current_sound = NULL;
7840ced1
GM
485 UNGCPRO;
486 unbind_to (count, Qnil);
487 return Qnil;
488}
489
490\f
491/***********************************************************************
492 Byte-order Conversion
493 ***********************************************************************/
494
495/* Convert 32-bit value VALUE which is in little-endian byte-order
496 to host byte-order. */
497
498static u_int32_t
499le2hl (value)
500 u_int32_t value;
501{
502#ifdef WORDS_BIG_ENDIAN
503 unsigned char *p = (unsigned char *) &value;
504 value = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
505#endif
506 return value;
507}
508
509
510/* Convert 16-bit value VALUE which is in little-endian byte-order
511 to host byte-order. */
512
513static u_int16_t
514le2hs (value)
515 u_int16_t value;
516{
517#ifdef WORDS_BIG_ENDIAN
518 unsigned char *p = (unsigned char *) &value;
519 value = p[0] + (p[1] << 8);
520#endif
521 return value;
522}
523
524
525/* Convert 32-bit value VALUE which is in big-endian byte-order
526 to host byte-order. */
527
528static u_int32_t
529be2hl (value)
530 u_int32_t value;
531{
532#ifndef WORDS_BIG_ENDIAN
533 unsigned char *p = (unsigned char *) &value;
534 value = p[3] + (p[2] << 8) + (p[1] << 16) + (p[0] << 24);
535#endif
536 return value;
537}
538
539
9680b9d0
GM
540#if 0 /* Currently not used. */
541
7840ced1
GM
542/* Convert 16-bit value VALUE which is in big-endian byte-order
543 to host byte-order. */
544
545static u_int16_t
546be2hs (value)
547 u_int16_t value;
548{
549#ifndef WORDS_BIG_ENDIAN
550 unsigned char *p = (unsigned char *) &value;
551 value = p[1] + (p[0] << 8);
552#endif
553 return value;
554}
555
9680b9d0 556#endif /* 0 */
7840ced1
GM
557
558\f
559/***********************************************************************
560 RIFF-WAVE (*.wav)
561 ***********************************************************************/
562
d1299cde 563/* Try to initialize sound file S from S->header. S->header
7840ced1
GM
564 contains the first MAX_SOUND_HEADER_BYTES number of bytes from the
565 sound file. If the file is a WAV-format file, set up interface
d1299cde 566 functions in S and convert header fields to host byte-order.
7840ced1
GM
567 Value is non-zero if the file is a WAV file. */
568
569static int
d1299cde
GM
570wav_init (s)
571 struct sound *s;
7840ced1 572{
d1299cde
GM
573 struct wav_header *header = (struct wav_header *) s->header;
574
575 if (s->header_size < sizeof *header
576 || bcmp (s->header, "RIFF", 4) != 0)
7840ced1
GM
577 return 0;
578
579 /* WAV files are in little-endian order. Convert the header
580 if on a big-endian machine. */
581 header->magic = le2hl (header->magic);
582 header->length = le2hl (header->length);
583 header->chunk_type = le2hl (header->chunk_type);
584 header->chunk_format = le2hl (header->chunk_format);
585 header->chunk_length = le2hl (header->chunk_length);
586 header->format = le2hs (header->format);
587 header->channels = le2hs (header->channels);
588 header->sample_rate = le2hl (header->sample_rate);
589 header->bytes_per_second = le2hl (header->bytes_per_second);
590 header->sample_size = le2hs (header->sample_size);
591 header->precision = le2hs (header->precision);
592 header->chunk_data = le2hl (header->chunk_data);
593 header->data_length = le2hl (header->data_length);
594
595 /* Set up the interface functions for WAV. */
d1299cde
GM
596 s->type = RIFF;
597 s->play = wav_play;
7840ced1
GM
598
599 return 1;
a4ff5d67 600}
7840ced1
GM
601
602
d1299cde 603/* Play RIFF-WAVE audio file S on sound device SD. */
7840ced1
GM
604
605static void
d1299cde
GM
606wav_play (s, sd)
607 struct sound *s;
7840ced1
GM
608 struct sound_device *sd;
609{
d1299cde 610 struct wav_header *header = (struct wav_header *) s->header;
7840ced1
GM
611
612 /* Let the device choose a suitable device-dependent format
613 for the file. */
d1299cde 614 sd->choose_format (sd, s);
a4ff5d67 615
7840ced1
GM
616 /* Configure the device. */
617 sd->sample_size = header->sample_size;
618 sd->sample_rate = header->sample_rate;
619 sd->bps = header->bytes_per_second;
620 sd->channels = header->channels;
621 sd->configure (sd);
622
623 /* Copy sound data to the device. The WAV file specification is
624 actually more complex. This simple scheme worked with all WAV
625 files I found so far. If someone feels inclined to implement the
626 whole RIFF-WAVE spec, please do. */
d1299cde 627 if (STRINGP (s->data))
d5db4077
KR
628 sd->write (sd, SDATA (s->data) + sizeof *header,
629 SBYTES (s->data) - sizeof *header);
d1299cde
GM
630 else
631 {
632 char *buffer;
633 int nbytes;
634 int blksize = 2048;
a4ff5d67 635
d1299cde
GM
636 buffer = (char *) alloca (blksize);
637 lseek (s->fd, sizeof *header, SEEK_SET);
a4ff5d67 638
d1299cde
GM
639 while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
640 sd->write (sd, buffer, nbytes);
7840ced1 641
d1299cde 642 if (nbytes < 0)
62725a92 643 sound_perror ("Error reading sound file");
d1299cde 644 }
7840ced1
GM
645}
646
647
648\f
649/***********************************************************************
650 Sun Audio (*.au)
651 ***********************************************************************/
652
a4ff5d67 653/* Sun audio file encodings. */
7840ced1
GM
654
655enum au_encoding
656{
657 AU_ENCODING_ULAW_8 = 1,
658 AU_ENCODING_8,
659 AU_ENCODING_16,
660 AU_ENCODING_24,
661 AU_ENCODING_32,
662 AU_ENCODING_IEEE32,
663 AU_ENCODING_IEEE64,
664 AU_COMPRESSED = 23
665};
666
667
d1299cde 668/* Try to initialize sound file S from S->header. S->header
7840ced1
GM
669 contains the first MAX_SOUND_HEADER_BYTES number of bytes from the
670 sound file. If the file is a AU-format file, set up interface
d1299cde 671 functions in S and convert header fields to host byte-order.
7840ced1
GM
672 Value is non-zero if the file is an AU file. */
673
674static int
d1299cde
GM
675au_init (s)
676 struct sound *s;
7840ced1 677{
d1299cde 678 struct au_header *header = (struct au_header *) s->header;
a4ff5d67 679
d1299cde
GM
680 if (s->header_size < sizeof *header
681 || bcmp (s->header, ".snd", 4) != 0)
7840ced1 682 return 0;
a4ff5d67 683
7840ced1
GM
684 header->magic_number = be2hl (header->magic_number);
685 header->data_offset = be2hl (header->data_offset);
686 header->data_size = be2hl (header->data_size);
687 header->encoding = be2hl (header->encoding);
688 header->sample_rate = be2hl (header->sample_rate);
689 header->channels = be2hl (header->channels);
a4ff5d67 690
7840ced1 691 /* Set up the interface functions for AU. */
d1299cde
GM
692 s->type = SUN_AUDIO;
693 s->play = au_play;
7840ced1
GM
694
695 return 1;
696}
697
698
d1299cde 699/* Play Sun audio file S on sound device SD. */
7840ced1
GM
700
701static void
d1299cde
GM
702au_play (s, sd)
703 struct sound *s;
7840ced1
GM
704 struct sound_device *sd;
705{
d1299cde 706 struct au_header *header = (struct au_header *) s->header;
7840ced1
GM
707
708 sd->sample_size = 0;
709 sd->sample_rate = header->sample_rate;
710 sd->bps = 0;
711 sd->channels = header->channels;
d1299cde 712 sd->choose_format (sd, s);
7840ced1 713 sd->configure (sd);
d1299cde
GM
714
715 if (STRINGP (s->data))
d5db4077
KR
716 sd->write (sd, SDATA (s->data) + header->data_offset,
717 SBYTES (s->data) - header->data_offset);
d1299cde
GM
718 else
719 {
720 int blksize = 2048;
721 char *buffer;
722 int nbytes;
a4ff5d67 723
d1299cde
GM
724 /* Seek */
725 lseek (s->fd, header->data_offset, SEEK_SET);
a4ff5d67 726
d1299cde
GM
727 /* Copy sound data to the device. */
728 buffer = (char *) alloca (blksize);
729 while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
730 sd->write (sd, buffer, nbytes);
a4ff5d67 731
d1299cde 732 if (nbytes < 0)
62725a92 733 sound_perror ("Error reading sound file");
d1299cde 734 }
7840ced1
GM
735}
736
737
738\f
739/***********************************************************************
740 Voxware Driver Interface
741 ***********************************************************************/
742
743/* This driver is available on GNU/Linux, and the free BSDs. FreeBSD
744 has a compatible own driver aka Luigi's driver. */
745
746
747/* Open device SD. If SD->file is non-null, open that device,
748 otherwise use a default device name. */
749
750static void
751vox_open (sd)
752 struct sound_device *sd;
753{
754 char *file;
a4ff5d67 755
7840ced1
GM
756 /* Open the sound device. Default is /dev/dsp. */
757 if (sd->file)
758 file = sd->file;
759 else
80fcd514 760 file = DEFAULT_SOUND_DEVICE;
a4ff5d67 761
68c45bf0 762 sd->fd = emacs_open (file, O_WRONLY, 0);
7840ced1
GM
763 if (sd->fd < 0)
764 sound_perror (file);
765}
766
767
768/* Configure device SD from parameters in it. */
769
770static void
771vox_configure (sd)
772 struct sound_device *sd;
773{
28fcb7dc 774 int val;
a4ff5d67 775
7840ced1
GM
776 xassert (sd->fd >= 0);
777
bb6e8cee
GM
778 /* On GNU/Linux, it seems that the device driver doesn't like to be
779 interrupted by a signal. Block the ones we know to cause
780 troubles. */
b5cb1ada 781 turn_on_atimers (0);
bb6e8cee
GM
782#ifdef SIGIO
783 sigblock (sigmask (SIGIO));
784#endif
b5cb1ada 785
28fcb7dc
GM
786 val = sd->format;
787 if (ioctl (sd->fd, SNDCTL_DSP_SETFMT, &sd->format) < 0
788 || val != sd->format)
62725a92 789 sound_perror ("Could not set sound format");
7840ced1 790
28fcb7dc
GM
791 val = sd->channels != 1;
792 if (ioctl (sd->fd, SNDCTL_DSP_STEREO, &val) < 0
793 || val != (sd->channels != 1))
62725a92 794 sound_perror ("Could not set stereo/mono");
7840ced1 795
28fcb7dc
GM
796 /* I think bps and sampling_rate are the same, but who knows.
797 Check this. and use SND_DSP_SPEED for both. */
798 if (sd->sample_rate > 0)
799 {
800 val = sd->sample_rate;
62725a92
GM
801 if (ioctl (sd->fd, SNDCTL_DSP_SPEED, &sd->sample_rate) < 0)
802 sound_perror ("Could not set sound speed");
803 else if (val != sd->sample_rate)
804 sound_warning ("Could not set sample rate");
28fcb7dc 805 }
7840ced1 806
3887b449
GM
807 if (sd->volume > 0)
808 {
809 int volume = sd->volume & 0xff;
810 volume |= volume << 8;
28fcb7dc
GM
811 /* This may fail if there is no mixer. Ignore the failure. */
812 ioctl (sd->fd, SOUND_MIXER_WRITE_PCM, &volume);
3887b449 813 }
a4ff5d67 814
b5cb1ada 815 turn_on_atimers (1);
bb6e8cee
GM
816#ifdef SIGIO
817 sigunblock (sigmask (SIGIO));
818#endif
7840ced1
GM
819}
820
821
822/* Close device SD if it is open. */
823
824static void
825vox_close (sd)
826 struct sound_device *sd;
827{
828 if (sd->fd >= 0)
829 {
bb6e8cee
GM
830 /* On GNU/Linux, it seems that the device driver doesn't like to
831 be interrupted by a signal. Block the ones we know to cause
832 troubles. */
833#ifdef SIGIO
834 sigblock (sigmask (SIGIO));
835#endif
b5cb1ada 836 turn_on_atimers (0);
a4ff5d67 837
bb6e8cee 838 /* Flush sound data, and reset the device. */
7840ced1 839 ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
a4ff5d67 840
b5cb1ada 841 turn_on_atimers (1);
bb6e8cee
GM
842#ifdef SIGIO
843 sigunblock (sigmask (SIGIO));
844#endif
7840ced1
GM
845
846 /* Close the device. */
68c45bf0 847 emacs_close (sd->fd);
7840ced1
GM
848 sd->fd = -1;
849 }
850}
851
852
d1299cde 853/* Choose device-dependent format for device SD from sound file S. */
7840ced1
GM
854
855static void
d1299cde 856vox_choose_format (sd, s)
7840ced1 857 struct sound_device *sd;
d1299cde 858 struct sound *s;
7840ced1 859{
d1299cde 860 if (s->type == RIFF)
7840ced1 861 {
d1299cde 862 struct wav_header *h = (struct wav_header *) s->header;
7840ced1
GM
863 if (h->precision == 8)
864 sd->format = AFMT_U8;
865 else if (h->precision == 16)
866 sd->format = AFMT_S16_LE;
867 else
868 error ("Unsupported WAV file format");
869 }
d1299cde 870 else if (s->type == SUN_AUDIO)
7840ced1 871 {
d1299cde 872 struct au_header *header = (struct au_header *) s->header;
7840ced1
GM
873 switch (header->encoding)
874 {
875 case AU_ENCODING_ULAW_8:
876 case AU_ENCODING_IEEE32:
877 case AU_ENCODING_IEEE64:
878 sd->format = AFMT_MU_LAW;
879 break;
a4ff5d67 880
7840ced1
GM
881 case AU_ENCODING_8:
882 case AU_ENCODING_16:
883 case AU_ENCODING_24:
884 case AU_ENCODING_32:
885 sd->format = AFMT_S16_LE;
886 break;
887
888 default:
889 error ("Unsupported AU file format");
890 }
891 }
892 else
893 abort ();
894}
895
896
897/* Initialize device SD. Set up the interface functions in the device
898 structure. */
899
900static void
901vox_init (sd)
902 struct sound_device *sd;
903{
904 sd->fd = -1;
905 sd->open = vox_open;
906 sd->close = vox_close;
907 sd->configure = vox_configure;
908 sd->choose_format = vox_choose_format;
909 sd->write = vox_write;
910}
911
912
913/* Write NBYTES bytes from BUFFER to device SD. */
914
915static void
916vox_write (sd, buffer, nbytes)
917 struct sound_device *sd;
dca0fc1c 918 const char *buffer;
7840ced1
GM
919 int nbytes;
920{
68c45bf0 921 int nwritten = emacs_write (sd->fd, buffer, nbytes);
7840ced1 922 if (nwritten < 0)
62725a92 923 sound_perror ("Error writing to sound device");
7840ced1
GM
924}
925
926
927\f
928/***********************************************************************
929 Initialization
930 ***********************************************************************/
931
932void
933syms_of_sound ()
934{
935 QCdevice = intern (":device");
936 staticpro (&QCdevice);
937 QCvolume = intern (":volume");
938 staticpro (&QCvolume);
939 Qsound = intern ("sound");
940 staticpro (&Qsound);
2a53558d
GM
941 Qplay_sound_functions = intern ("play-sound-functions");
942 staticpro (&Qplay_sound_functions);
7840ced1 943
14e415e7 944 defsubr (&Splay_sound_internal);
7840ced1
GM
945}
946
947
948void
949init_sound ()
950{
951}
952
953#endif /* HAVE_SOUND */