annotate src/sgiplay.c @ 5518:3cc7470ea71c

gnuclient: if TMPDIR was set and connect failed, try again with /tmp 2011-06-03 Aidan Kehoe <kehoea@parhasard.net> * gnuslib.c (connect_to_unix_server): Retry with /tmp as a directory in which to search for Unix sockets if an attempt to connect with some other directory failed (which may be because gnuclient and gnuserv don't share an environment value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR turned off).
author Aidan Kehoe <kehoea@parhasard.net>
date Fri, 03 Jun 2011 18:40:57 +0100
parents 308d34e9f07d
children 56144c8593a8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Play sound using the SGI audio library
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 written by Simon Leinen <simon@lia.di.epfl.ch>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 Copyright (C) 1992 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 2367
diff changeset
7 XEmacs is free software: you can redistribute it and/or modify it
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 2367
diff changeset
9 Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 2367
diff changeset
10 option) any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 2367
diff changeset
18 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 /* Synched up with: Not in FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
22 /* This file Mule-ized by Ben Wing, 5-15-01. */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
23
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
27 #include "sound.h"
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
28
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
29 #include "sysfile.h"
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
30 #include "sysproc.h" /* netinet/in.h for ntohl() etc. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
32 #include <audio.h>
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
33
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 /* Configuration options */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 /* ability to parse Sun/NeXT (.au or .snd) audio file headers. The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 .snd format supports all sampling rates and sample widths that are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 commonly used, as well as stereo. It is also easy to parse. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 #ifndef HAVE_SND_FILES
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 #define HAVE_SND_FILES 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 /* support for eight-but mu-law encoding. This is a useful compaction
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 technique, and most sounds from the Sun universe are in this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 format. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 #ifndef HAVE_MULAW_8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 #define HAVE_MULAW_8 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 /* if your machine is very slow, you have to use a table lookup to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 convert mulaw samples to linear. This makes Emacs bigger so try to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 avoid it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 #ifndef USE_MULAW_DECODE_TABLE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 #define USE_MULAW_DECODE_TABLE 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 /* support for linear encoding -- useful if you want better quality.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 This enables 8, 16 and 24 bit wide samples. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 #ifndef HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 #define HAVE_LINEAR 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 /* support for 32 bit wide samples. If you notice the difference
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 between 32 and 24 bit samples, you must have very good ears. Since
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 the SGI audio library only supports 24 bit samples, each sample has
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 to be shifted right by 8 bits anyway. So you should probably just
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 convert all your 32 bit audio files to 24 bit. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 #ifndef HAVE_LINEAR_32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 #define HAVE_LINEAR_32 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 /* support for stereo sound. Imagine the cool applications of this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 finally you don't just hear a beep -- you also know immediately
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 *where* something went wrong! Unfortunately the programming
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 interface only takes a single volume argument so far. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 #ifndef HAVE_STEREO
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 #define HAVE_STEREO 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 /* the play routine can be interrupted between chunks, so we choose a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 small chunksize to keep the system responsive (2000 samples
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 correspond to a quarter of a second for .au files. If you
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 HAVE_STEREO, the chunksize should probably be even. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 #define CHUNKSIZE 8000
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 /* the format assumed for header-less audio data. The following
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 assumes ".au" format (8000 samples/sec mono 8-bit mulaw). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 #define DEFAULT_SAMPLING_RATE 8000
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 #define DEFAULT_CHANNEL_COUNT 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 #define DEFAULT_FORMAT AFmulaw8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 /* Data structures */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 /* an AudioContext describes everything we want to know about how a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 particular sound snippet should be played. It is split into three
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 parts (device, port and buffer) for implementation reasons. The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 device part corresponds to the state of the output device and must
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 be reverted after playing the samples. The port part corresponds
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 to an ALport; we want to allocate a minimal number of these since
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 there are only four of them system-wide, but on the other hand we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 can't use the same port for mono and stereo. The buffer part
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 corresponds to the sound data itself. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 typedef struct _AudioContextRec * AudioContext;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 typedef struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 long device;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 int left_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 int right_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 long output_rate;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 AudioDeviceRec, * AudioDevice;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 /* supported sound data formats */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 typedef enum
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 AFunknown,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 #if HAVE_MULAW_8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 AFmulaw8,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 AFlinear8,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 AFlinear16,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 AFlinear24,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 #if HAVE_LINEAR_32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 AFlinear32,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 AFillegal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 AudioFormat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 typedef struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ALport port;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 AudioFormat format;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 unsigned nchan;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 unsigned queue_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 AudioPortRec, * AudioPort;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 typedef struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 void * data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 unsigned long size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 void (* write_chunk_function) (void *, void *, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 AudioBufferRec, * AudioBuffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 typedef struct _AudioContextRec
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 AudioDeviceRec device;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 AudioPortRec port;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 AudioBufferRec buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 AudioContextRec;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 #define ac_device device.device
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 #define ac_left_speaker_gain device.left_speaker_gain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 #define ac_right_speaker_gain device.right_speaker_gain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 #define ac_output_rate device.output_rate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 #define ac_port port.port
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 #define ac_format port.format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 #define ac_nchan port.nchan
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 #define ac_queue_size port.queue_size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 #define ac_data buffer.data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 #define ac_size buffer.size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 #define ac_write_chunk_function buffer.write_chunk_function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 /* Forward declarations */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 static Lisp_Object close_sound_file (Lisp_Object);
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
175 static AudioContext audio_initialize (Binbyte *, int, int);
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
176 static int play_internal (Binbyte *, int, AudioContext);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 static void drain_audio_port (AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 static void write_mulaw_8_chunk (void *, void *, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 static void write_linear_chunk (void *, void *, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 static void write_linear_32_chunk (void *, void *, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 static Lisp_Object restore_audio_port (Lisp_Object);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 static AudioContext initialize_audio_port (AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 static int open_audio_port (AudioContext, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 static void adjust_audio_volume (AudioDevice);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 static void get_current_volumes (AudioDevice);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 static int set_channels (ALconfig, unsigned);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 static int set_output_format (ALconfig, AudioFormat);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 static int parse_snd_header (void*, long, AudioContext);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 /* are we looking at an NeXT/Sun audio header? */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 #define LOOKING_AT_SND_HEADER_P(address) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (!strncmp(".snd", (char *)(address), 4))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 close_sound_file (Lisp_Object closure)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 close (XINT (closure));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 void
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
202 play_sound_file (Extbyte *sound_file, int volume)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 int count = specpdl_depth ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 int input_fd;
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
206 Binbyte buffer[CHUNKSIZE];
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 int bytes_read;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 AudioContext ac = (AudioContext) 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 input_fd = open (sound_file, O_RDONLY);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 if (input_fd == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 /* no error message -- this can't happen
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 because Fplay_sound_file has checked the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 file for us. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 record_unwind_protect (close_sound_file, make_int (input_fd));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 while ((bytes_read = read (input_fd, buffer, CHUNKSIZE)) > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 if (ac == (AudioContext) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 ac = audio_initialize (buffer, bytes_read, volume);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 if (ac == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 ac->ac_data = buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 ac->ac_size = bytes_read;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 play_internal (buffer, bytes_read, ac);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 drain_audio_port (ac);
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 609
diff changeset
235 unbind_to (count);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 static long
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 saved_device_state[] = {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 AL_OUTPUT_RATE, 0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 AL_LEFT_SPEAKER_GAIN, 0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 AL_RIGHT_SPEAKER_GAIN, 0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 restore_audio_port (Lisp_Object closure)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 Lisp_Object * contents = XVECTOR_DATA (closure);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 saved_device_state[1] = XINT (contents[0]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 saved_device_state[3] = XINT (contents[1]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 saved_device_state[5] = XINT (contents[2]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 ALsetparams (AL_DEFAULT_DEVICE, saved_device_state, 6);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
256 int
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
257 play_sound_data (Binbyte *data, int length, int volume)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 int count = specpdl_depth ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 AudioContext ac;
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
261 int result;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ac = audio_initialize (data, length, volume);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 if (ac == (AudioContext) 0)
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
265 return 0;
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
266 result = play_internal (data, length, ac);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 drain_audio_port (ac);
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 609
diff changeset
268 unbind_to (count);
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
269 return result;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 static AudioContext
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
273 audio_initialize (Binbyte *data, int length, int volume)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 Lisp_Object audio_port_state[3];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 static AudioContextRec desc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 AudioContext ac;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 desc.ac_right_speaker_gain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 = desc.ac_left_speaker_gain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 = volume * 256 / 100;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 desc.ac_device = AL_DEFAULT_DEVICE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 #if HAVE_SND_FILES
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 if (LOOKING_AT_SND_HEADER_P (data))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 if (parse_snd_header (data, length, & desc)==-1)
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
288 report_sound_error ("decoding .snd header", Qunbound);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 desc.ac_data = data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 desc.ac_size = length;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 desc.ac_output_rate = DEFAULT_SAMPLING_RATE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 desc.ac_nchan = DEFAULT_CHANNEL_COUNT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 desc.ac_format = DEFAULT_FORMAT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 desc.ac_write_chunk_function = write_mulaw_8_chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 /* Make sure that the audio port is reset to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 its initial characteristics after exit */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 ALgetparams (desc.ac_device, saved_device_state,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 sizeof (saved_device_state) / sizeof (long));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 audio_port_state[0] = make_int (saved_device_state[1]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 audio_port_state[1] = make_int (saved_device_state[3]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 audio_port_state[2] = make_int (saved_device_state[5]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 record_unwind_protect (restore_audio_port,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 Fvector (3, &audio_port_state[0]));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 ac = initialize_audio_port (& desc);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 desc = * ac;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 return ac;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
316 static int
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
317 play_internal (Binbyte *data, int UNUSED (length), AudioContext ac)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 {
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
319 Binbyte * limit;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 if (ac == (AudioContext) 0)
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
321 return 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
323 data = (Binbyte *) ac->ac_data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 limit = data + ac->ac_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 while (data < limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 {
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
327 Binbyte * chunklimit = data + CHUNKSIZE;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 if (chunklimit > limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 chunklimit = limit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 QUIT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (* ac->ac_write_chunk_function) (data, chunklimit, ac);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 data = chunklimit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 }
609
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
337
13e3d7ae7155 [xemacs-hg @ 2001-06-06 12:34:42 by ben]
ben
parents: 563
diff changeset
338 return 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 drain_audio_port (AudioContext ac)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 while (ALgetfilled (ac->ac_port) > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 sginap(1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 /* Methods to write a "chunk" from a buffer containing audio data to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 an audio port. This may involve some conversion if the output
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 device doesn't directly support the format the audio data is in. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 #if HAVE_MULAW_8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 #if USE_MULAW_DECODE_TABLE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 #include "libst.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 #else /* not USE_MULAW_DECODE_TABLE */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 st_ulaw_to_linear (int u)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
360 static const short table[] = {0,132,396,924,1980,4092,8316,16764};
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 int u1 = ~u;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 short exponent = (u1 >> 4) & 0x07;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 int mantissa = u1 & 0x0f;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 int unsigned_result = table[exponent]+(mantissa << (exponent+3));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 return u1 & 0x80 ? -unsigned_result : unsigned_result;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 #endif /* not USE_MULAW_DECODE_TABLE */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 write_mulaw_8_chunk (void *buffer, void *chunklimit, AudioContext ac)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 {
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
372 Binbyte * data = (Binbyte *) buffer;
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
373 Binbyte * limit = (Binbyte *) chunklimit;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 short * obuf, * bufp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 long n_samples = limit - data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 obuf = alloca_array (short, n_samples);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 bufp = &obuf[0];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 while (data < limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 *bufp++ = st_ulaw_to_linear (*data++);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 ALwritesamps (ac->ac_port, obuf, n_samples);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 #endif /* HAVE_MULAW_8 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 write_linear_chunk (void *data, void *limit, AudioContext ac)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 unsigned n_samples;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 switch (ac->ac_format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 case AFlinear16: n_samples = (short *) limit - (short *) data; break;
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
395 case AFlinear8: n_samples = (CBinbyte *) limit - (CBinbyte *) data; break;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 default: n_samples = (long *) limit - (long *) data; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 ALwritesamps (ac->ac_port, data, (long) n_samples);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 #if HAVE_LINEAR_32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 write_linear_32_chunk (void *buffer, void *chunklimit, AudioContext ac)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 long * data = (long *) buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 long * limit = (long *) chunklimit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 long * obuf, * bufp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 long n_samples = limit-data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 obuf = alloca_array (long, n_samples);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 bufp = &obuf[0];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 while (data < limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 *bufp++ = *data++ >> 8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 ALwritesamps (ac->ac_port, obuf, n_samples);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 #endif /* HAVE_LINEAR_32 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 #endif /* HAVE_LINEAR */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 static AudioContext
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 initialize_audio_port (AudioContext desc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 /* we can't use the same port for mono and stereo */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 static AudioContextRec mono_port_state
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 = { { 0, 0, 0, 0 },
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 { (ALport) 0, AFunknown, 1, 0 },
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 { (void *) 0, (unsigned long) 0 } };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 #if HAVE_STEREO
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 static AudioContextRec stereo_port_state
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 = { { 0, 0, 0, 0 },
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 { (ALport) 0, AFunknown, 2, 0 },
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 { (void *) 0, (unsigned long) 0 } };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 static AudioContext return_ac;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 switch (desc->ac_nchan)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 case 1: return_ac = & mono_port_state; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 case 2: return_ac = & stereo_port_state; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 default: return (AudioContext) 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 #else /* not HAVE_STEREO */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 static AudioContext return_ac = & mono_port_state;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 #endif /* not HAVE_STEREO */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 return_ac->device = desc->device;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 return_ac->buffer = desc->buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 return_ac->ac_format = desc->ac_format;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 return_ac->ac_queue_size = desc->ac_queue_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 if (return_ac->ac_port==(ALport) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 if ((open_audio_port (return_ac, desc))==-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
454 report_sound_error ("Open audio port", Qunbound);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 return (AudioContext) 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 ALconfig config = ALgetconfig (return_ac->ac_port);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 int changed = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 long params[2];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 params[0] = AL_OUTPUT_RATE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 ALgetparams (return_ac->ac_device, params, 2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 return_ac->ac_output_rate = params[1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 if (return_ac->ac_output_rate != desc->ac_output_rate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 return_ac->ac_output_rate = params[1] = desc->ac_output_rate;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 ALsetparams (return_ac->ac_device, params, 2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 if ((changed = set_output_format (config, return_ac->ac_format))==-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 return (AudioContext) 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 return_ac->ac_format = desc->ac_format;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 if (changed)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 ALsetconfig (return_ac->ac_port, config);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 return_ac->ac_write_chunk_function = desc->ac_write_chunk_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 get_current_volumes (& return_ac->device);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 if (return_ac->ac_left_speaker_gain != desc->ac_left_speaker_gain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 || return_ac->ac_right_speaker_gain != desc->ac_right_speaker_gain)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 adjust_audio_volume (& desc->device);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 return return_ac;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 open_audio_port (AudioContext return_ac, AudioContext desc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 ALconfig config = ALnewconfig();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 long params[2];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 adjust_audio_volume (& desc->device);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 return_ac->ac_left_speaker_gain = desc->ac_left_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 return_ac->ac_right_speaker_gain = desc->ac_right_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 params[0] = AL_OUTPUT_RATE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 params[1] = desc->ac_output_rate;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 ALsetparams (desc->ac_device, params, 2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 return_ac->ac_output_rate = desc->ac_output_rate;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 if (set_channels (config, desc->ac_nchan)==-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 return_ac->ac_nchan = desc->ac_nchan;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 if (set_output_format (config, desc->ac_format)==-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 return_ac->ac_format = desc->ac_format;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ALsetqueuesize (config, (long) CHUNKSIZE);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 return_ac->ac_port = ALopenport("XEmacs audio output", "w", config);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ALfreeconfig (config);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 if (return_ac->ac_port==0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
511 report_sound_error ("Opening audio output port", Qunbound);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 set_channels (ALconfig config, unsigned int nchan)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 switch (nchan)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 case 1: ALsetchannels (config, AL_MONO); break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 #if HAVE_STEREO
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 case 2: ALsetchannels (config, AL_STEREO); break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 #endif /* HAVE_STEREO */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 default:
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
527 report_sound_error ("Unsupported channel count",
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
528 make_int (nchan));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 set_output_format (ALconfig config, AudioFormat format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 long samplesize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 long old_samplesize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 switch (format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 #if HAVE_MULAW_8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 case AFmulaw8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 case AFlinear16:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 #if HAVE_MULAW_8 || HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 samplesize = AL_SAMPLE_16;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 case AFlinear8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 samplesize = AL_SAMPLE_8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 case AFlinear24:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 #if HAVE_LINEAR_32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 case AFlinear32:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 samplesize = AL_SAMPLE_24;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 default:
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 444
diff changeset
564 report_sound_error ("Unsupported audio format", make_int (format));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 old_samplesize = ALgetwidth (config);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 if (old_samplesize==samplesize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 ALsetwidth (config, samplesize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 adjust_audio_volume (AudioDevice device)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 long params[4];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 params[0] = AL_LEFT_SPEAKER_GAIN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 params[1] = device->left_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 params[2] = AL_RIGHT_SPEAKER_GAIN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 params[3] = device->right_speaker_gain;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 ALsetparams (device->device, params, 4);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 get_current_volumes (AudioDevice device)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 long params[4];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 params[0] = AL_LEFT_SPEAKER_GAIN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 params[2] = AL_RIGHT_SPEAKER_GAIN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 ALgetparams (device->device, params, 4);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 device->left_speaker_gain = params[1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 device->right_speaker_gain = params[3];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 #if HAVE_SND_FILES
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 /* Parsing .snd (NeXT/Sun) headers */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 typedef struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 int magic;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 int dataLocation;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 int dataSize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 int dataFormat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 int samplingRate;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 int channelCount;
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
608 CBinbyte info[4];
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 SNDSoundStruct;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 #define SOUND_TO_HOST_INT(x) ntohl(x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 typedef enum
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 SND_FORMAT_FORMAT_UNSPECIFIED,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 SND_FORMAT_MULAW_8,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 SND_FORMAT_LINEAR_8,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 SND_FORMAT_LINEAR_16,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 SND_FORMAT_LINEAR_24,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 SND_FORMAT_LINEAR_32,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 SND_FORMAT_FLOAT,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 SND_FORMAT_DOUBLE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 SND_FORMAT_INDIRECT,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 SND_FORMAT_NESTED,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 SND_FORMAT_DSP_CODE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 SND_FORMAT_DSP_DATA_8,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 SND_FORMAT_DSP_DATA_16,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 SND_FORMAT_DSP_DATA_24,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 SND_FORMAT_DSP_DATA_32,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 SND_FORMAT_DSP_unknown_15,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 SND_FORMAT_DISPLAY,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 SND_FORMAT_MULAW_SQUELCH,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 SND_FORMAT_EMPHASIZED,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 SND_FORMAT_COMPRESSED,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 SND_FORMAT_COMPRESSED_EMPHASIZED,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 SND_FORMAT_DSP_COMMANDS,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 SND_FORMAT_DSP_COMMANDS_SAMPLES
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 SNDFormatCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 parse_snd_header (void *header, long length, AudioContext desc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 #define hp ((SNDSoundStruct *) (header))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 long limit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 desc->ac_write_chunk_function = write_linear_chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 switch ((SNDFormatCode) SOUND_TO_HOST_INT (hp->dataFormat))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 #if HAVE_MULAW_8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 case SND_FORMAT_MULAW_8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 desc->ac_format = AFmulaw8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 desc->ac_write_chunk_function = write_mulaw_8_chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 #if HAVE_LINEAR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 case SND_FORMAT_LINEAR_8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 desc->ac_format = AFlinear8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 case SND_FORMAT_LINEAR_16:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 desc->ac_format = AFlinear16;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 case SND_FORMAT_LINEAR_24:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 desc->ac_format = AFlinear24;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 #if HAVE_LINEAR_32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 case SND_FORMAT_LINEAR_32:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 desc->ac_format = AFlinear32;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 desc->ac_write_chunk_function = write_linear_32_chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 default:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 desc->ac_format = AFunknown;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 desc->ac_output_rate = SOUND_TO_HOST_INT (hp->samplingRate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 desc->ac_nchan = SOUND_TO_HOST_INT (hp->channelCount);
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
680 desc->ac_data = (CBinbyte *) header + SOUND_TO_HOST_INT (hp->dataLocation);
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 2286
diff changeset
681 limit = (CBinbyte *) header + length - (CBinbyte *) desc->ac_data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 desc->ac_size = SOUND_TO_HOST_INT (hp->dataSize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 if (desc->ac_size > limit) desc->ac_size = limit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 #undef hp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 #endif /* HAVE_SND_FILES */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688