{
/* ASCII ".snd" */
u_int32_t magic_number;
-
+
/* Offset of data part from start of file. Minimum value is 24. */
u_int32_t data_offset;
-
+
/* Size of data part, 0xffffffff if unknown. */
u_int32_t data_size;
/* 1 = mono, 2 = stereo, 0 = don't set. */
int channels;
-
+
/* Open device SD. */
void (* open) P_ ((struct sound_device *sd));
/* Configure SD accoring to device-dependent parameters. */
void (* configure) P_ ((struct sound_device *device));
-
+
/* Choose a device-dependent format for outputting sound S. */
void (* choose_format) P_ ((struct sound_device *sd,
struct sound *s));
/* Write NYBTES bytes from BUFFER to device SD. */
- void (* write) P_ ((struct sound_device *sd, char *buffer, int nbytes));
+ void (* write) P_ ((struct sound_device *sd, const char *buffer,
+ int nbytes));
/* A place for devices to store additional data. */
void *data;
Lisp_Object data;
/* Play sound file S on device SD. */
- void (* play) P_ ((struct sound *s, struct sound_device *sd));
+ void (* play) P_ ((struct sound *s, struct sound_device *sd));
};
/* Indices of attributes in a sound attributes vector. */
Lisp_Object Qsound;
Lisp_Object Qplay_sound_functions;
-/* These are set during `play-sound' so that sound_cleanup has
+/* These are set during `play-sound-internal' so that sound_cleanup has
access to them. */
struct sound_device *current_sound_device;
static void vox_close P_ ((struct sound_device *sd));
static void vox_choose_format P_ ((struct sound_device *, struct sound *));
static void vox_init P_ ((struct sound_device *));
-static void vox_write P_ ((struct sound_device *, char *, int));
+static void vox_write P_ ((struct sound_device *, const char *, int));
static void sound_perror P_ ((char *));
static void sound_warning P_ ((char *));
static int parse_sound P_ ((Lisp_Object, Lisp_Object *));
sound_perror (msg)
char *msg;
{
+ int saved_errno = errno;
+
turn_on_atimers (1);
#ifdef SIGIO
sigunblock (sigmask (SIGIO));
#endif
- if (errno != 0)
- error ("%s: %s", msg, strerror (errno));
+ if (saved_errno != 0)
+ error ("%s: %s", msg, strerror (saved_errno));
else
error ("%s", msg);
}
}
-/* Function installed by play-sound with record_unwind_protect. */
+/* Function installed by play-sound-internal with record_unwind_protect. */
static Lisp_Object
sound_cleanup (arg)
}
-DEFUN ("play-sound", Fplay_sound, Splay_sound, 1, 1, 0,
+DEFUN ("play-sound-internal", Fplay_sound_internal, Splay_sound_internal, 1, 1, 0,
doc: /* Play sound SOUND.
-SOUND is a list of the form `(sound KEYWORD VALUE...)'.
-The following keywords are recognized:
-
- :file FILE.- read sound data from FILE. If FILE isn't an
-absolute file name, it is searched in `data-directory'.
-
- :data DATA - read sound data from string DATA.
-Exactly one of :file or :data must be present.
-
- :volume VOL - set volume to VOL. VOL must an integer in the
-range 0..100 or a float in the range 0..1.0. If not specified,
-don't change the volume setting of the sound device.
-
- :device DEVICE - play sound on DEVICE. If not specified,
-a system-dependent default device name is used. */)
+Internal use only, use `play-sound' instead. */)
(sound)
Lisp_Object sound;
{
struct sound_device sd;
struct sound s;
Lisp_Object args[2];
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
file = Qnil;
GCPRO2 (sound, file);
{
/* Open the sound file. */
s.fd = openp (Fcons (Vdata_directory, Qnil),
- attrs[SOUND_FILE], Qnil, &file, 0);
+ attrs[SOUND_FILE], Qnil, &file, Qnil);
if (s.fd < 0)
sound_perror ("Could not open sound file");
else
{
s.data = attrs[SOUND_DATA];
- bcopy (XSTRING (s.data)->data, s.header,
- min (MAX_SOUND_HEADER_BYTES, STRING_BYTES (XSTRING (s.data))));
+ s.header_size = min (MAX_SOUND_HEADER_BYTES, SBYTES (s.data));
+ bcopy (SDATA (s.data), s.header, s.header_size);
}
/* Find out the type of sound. Give up if we can't tell. */
/* Set up a device. */
if (STRINGP (attrs[SOUND_DEVICE]))
{
- int len = XSTRING (attrs[SOUND_DEVICE])->size;
+ int len = SCHARS (attrs[SOUND_DEVICE]);
sd.file = (char *) alloca (len + 1);
- strcpy (sd.file, XSTRING (attrs[SOUND_DEVICE])->data);
+ strcpy (sd.file, SDATA (attrs[SOUND_DEVICE]));
}
-
+
if (INTEGERP (attrs[SOUND_VOLUME]))
sd.volume = XFASTINT (attrs[SOUND_VOLUME]);
else if (FLOATP (attrs[SOUND_VOLUME]))
s->play = wav_play;
return 1;
-}
+}
/* Play RIFF-WAVE audio file S on sound device SD. */
/* Let the device choose a suitable device-dependent format
for the file. */
sd->choose_format (sd, s);
-
+
/* Configure the device. */
sd->sample_size = header->sample_size;
sd->sample_rate = header->sample_rate;
files I found so far. If someone feels inclined to implement the
whole RIFF-WAVE spec, please do. */
if (STRINGP (s->data))
- sd->write (sd, XSTRING (s->data)->data + sizeof *header,
- STRING_BYTES (XSTRING (s->data)) - sizeof *header);
+ sd->write (sd, SDATA (s->data) + sizeof *header,
+ SBYTES (s->data) - sizeof *header);
else
{
char *buffer;
int nbytes;
int blksize = 2048;
-
+
buffer = (char *) alloca (blksize);
lseek (s->fd, sizeof *header, SEEK_SET);
-
+
while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
sd->write (sd, buffer, nbytes);
Sun Audio (*.au)
***********************************************************************/
-/* Sun audio file encodings. */
+/* Sun audio file encodings. */
enum au_encoding
{
struct sound *s;
{
struct au_header *header = (struct au_header *) s->header;
-
+
if (s->header_size < sizeof *header
|| bcmp (s->header, ".snd", 4) != 0)
return 0;
-
+
header->magic_number = be2hl (header->magic_number);
header->data_offset = be2hl (header->data_offset);
header->data_size = be2hl (header->data_size);
header->encoding = be2hl (header->encoding);
header->sample_rate = be2hl (header->sample_rate);
header->channels = be2hl (header->channels);
-
+
/* Set up the interface functions for AU. */
s->type = SUN_AUDIO;
s->play = au_play;
sd->configure (sd);
if (STRINGP (s->data))
- sd->write (sd, XSTRING (s->data)->data + header->data_offset,
- STRING_BYTES (XSTRING (s->data)) - header->data_offset);
+ sd->write (sd, SDATA (s->data) + header->data_offset,
+ SBYTES (s->data) - header->data_offset);
else
{
int blksize = 2048;
char *buffer;
int nbytes;
-
+
/* Seek */
lseek (s->fd, header->data_offset, SEEK_SET);
-
+
/* Copy sound data to the device. */
buffer = (char *) alloca (blksize);
while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
sd->write (sd, buffer, nbytes);
-
+
if (nbytes < 0)
sound_perror ("Error reading sound file");
}
struct sound_device *sd;
{
char *file;
-
+
/* Open the sound device. Default is /dev/dsp. */
if (sd->file)
file = sd->file;
else
file = DEFAULT_SOUND_DEVICE;
-
+
sd->fd = emacs_open (file, O_WRONLY, 0);
if (sd->fd < 0)
sound_perror (file);
struct sound_device *sd;
{
int val;
-
+
xassert (sd->fd >= 0);
/* On GNU/Linux, it seems that the device driver doesn't like to be
/* This may fail if there is no mixer. Ignore the failure. */
ioctl (sd->fd, SOUND_MIXER_WRITE_PCM, &volume);
}
-
+
turn_on_atimers (1);
#ifdef SIGIO
sigunblock (sigmask (SIGIO));
sigblock (sigmask (SIGIO));
#endif
turn_on_atimers (0);
-
+
/* Flush sound data, and reset the device. */
ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
-
+
turn_on_atimers (1);
#ifdef SIGIO
sigunblock (sigmask (SIGIO));
case AU_ENCODING_IEEE64:
sd->format = AFMT_MU_LAW;
break;
-
+
case AU_ENCODING_8:
case AU_ENCODING_16:
case AU_ENCODING_24:
static void
vox_write (sd, buffer, nbytes)
struct sound_device *sd;
- char *buffer;
+ const char *buffer;
int nbytes;
{
int nwritten = emacs_write (sd->fd, buffer, nbytes);
Qplay_sound_functions = intern ("play-sound-functions");
staticpro (&Qplay_sound_functions);
- defsubr (&Splay_sound);
+ defsubr (&Splay_sound_internal);
}