Partially sync files.el from XEmacs 21.5 for wildcard support.
[sxemacs] / src / media / sound-hpplay.c
1 /* Copyright (C) 1993 Free Software Foundation, Inc.
2
3 This file is part of SXEmacs
4
5 SXEmacs is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 SXEmacs is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
18
19 /* Synched up with: Not in FSF. */
20
21 /***
22    NAME
23      hpplay
24    PURPOSE
25      Play .au sound files on hp9000s700
26    BUGS
27      I have been unable to figure out how to use the volume feature, so no
28      attempt has been made to honor the volume arg of play_sound_*
29      This means that all sounds are played at 100%.
30      The gain parameter can be set by using the hp-play-gain variable.
31
32    NOTES
33      This file is mostly based on the player program found in the examples
34      directory of the audio software delivered on our machines. The path I
35      found it under was /usr/audio/examples/player.c
36      This file contained no credits and no copyrights. The original fileheader
37      is given below.
38    HISTORY
39      lynbech - Feb 10, 1993: Created.
40 ***/
41
42 /* ORIGINAL FILEHEADER:
43  * player - command-line audio file player
44  *   Aug. 28 1991
45  *    by three unknown, unsung audio programmers
46  *     (well, only two are unsung)
47  */
48
49 #include <config.h>
50 #include "lisp.h"
51
52 #include "nativesound.h"
53
54 #include <stdlib.h>
55 #include <stdio.h>
56 #ifdef HPUX10
57 #include <Alib.h>
58 #include <CUlib.h>
59 #else                           /* !HPUX 10 */
60 #include <audio/Alib.h>
61 #include <audio/CUlib.h>
62 #endif                          /* !HPUX 10 */
63
64 Lisp_Object Vhp_play_server;
65 Lisp_Object Vhp_play_speaker;
66 Fixnum hp_play_gain;
67
68 /* Functions */
69
70 /* error handling */
71 void player_error_internal(Audio * audio, char *text, long errorCode)
72 {
73         char errorbuff[132], buf[256];
74         int sz;
75
76         AGetErrorText(audio, errorCode, errorbuff, 131);
77         sz = sprintf(buf, sizeof(buf), "%s: %s\n", text, errorbuff);
78         assert(sz>=0 && sz<sizeof(buf));
79         error(buf);
80 }
81
82 long myHandler(audio, err_event)
83 Audio *audio;
84 AErrorEvent *err_event;
85 {
86         player_error_internal(audio, "Internal sound error",
87                               err_event->error_code);
88         return 1;               /* Must return something, was orig. an exit */
89 }
90
91 /* Playing */
92 void play_bucket_internal(audio, pSBucket, volume)
93 Audio *audio;
94 SBucket *pSBucket;
95 long volume;
96 {
97         SBPlayParams playParams;
98         AGainEntry gainEntry;
99         ATransID xid;
100         long status;
101         char *speaker;
102
103         playParams.priority = APriorityNormal;  /* normal priority */
104
105         /*
106          * We can't signal an error, because all h*ll would break loose if
107          * we did.
108          */
109         if (SYMBOLP(Vhp_play_speaker)) {
110                 speaker =
111                     (char *)(string_data(XSYMBOL(Vhp_play_speaker)->name));
112
113                 /*
114                  * setup the playback parameters
115                  */
116
117                 /* speaker selection */
118                 if (strcmp(speaker, "external") == 0) {
119                         gainEntry.u.o.out_dst = AODTMonoJack;
120                 } else {
121                         gainEntry.u.o.out_dst = AODTMonoIntSpeaker;
122                 }
123         } else {
124                 /*
125                  * Quietly revert to the internal speaker
126                  */
127                 gainEntry.u.o.out_dst = AODTMonoIntSpeaker;
128         }
129
130         gainEntry.u.o.out_ch = AOCTMono;
131         gainEntry.gain = AUnityGain;
132         playParams.gain_matrix.type = AGMTOutput;       /* gain matrix */
133         playParams.gain_matrix.num_entries = 1;
134         playParams.gain_matrix.gain_entries = &gainEntry;
135         playParams.play_volume = hp_play_gain;  /* play volume */
136         playParams.pause_first = False; /* don't pause */
137         playParams.start_offset.type = ATTSamples;      /* start offset 0 */
138         playParams.start_offset.u.samples = 0;
139         playParams.duration.type = ATTFullLength;       /* play entire sample */
140         playParams.loop_count = 1;      /* play sample just once */
141         playParams.previous_transaction = 0;    /* no linked transaction */
142         playParams.event_mask = 0;      /* don't solicit any events */
143
144         /*
145          * play the sound bucket
146          */
147         xid = APlaySBucket(audio, pSBucket, &playParams, NULL);
148
149         /*
150          * set close mode to prevent playback from stopping
151          *  when we close audio connection
152          */
153         ASetCloseDownMode(audio, AKeepTransactions, &status);
154
155         /*
156          *  That's all, folks!
157          *  Always destroy bucket and close connection.
158          */
159         ADestroySBucket(audio, pSBucket, &status);
160         ACloseAudio(audio, &status);
161 }
162
163 void play_sound_file(sound_file, volume)
164 char *sound_file;
165 int volume;
166 {
167         SBucket *pSBucket;
168         Audio *audio;
169         long status;
170         AErrorHandler prevHandler;      /* pointer to previous handler */
171         char *server;
172
173         if (STRINGP(Vhp_play_server))
174                 server = (char *)XSTRING_DATA(Vhp_play_server);
175         server = "";
176
177         /*
178          *  open audio connection
179          */
180         audio = AOpenAudio(server, &status);
181         if (status) {
182                 player_error_internal(audio, "Open audio failed", status);
183         }
184
185         /* replace default error handler */
186         prevHandler = ASetErrorHandler(myHandler);
187
188         /*
189          *  Load the audio file into a sound bucket
190          */
191
192         pSBucket = ALoadAFile(audio, sound_file, AFFUnknown, 0, NULL, NULL);
193
194         /*
195          * Play the bucket
196          */
197
198         play_bucket_internal(audio, pSBucket, volume);
199
200         ASetErrorHandler(prevHandler);
201 }
202
203 int play_sound_data(data, length, volume)
204 unsigned char *data;
205 int length;
206 int volume;
207 {
208         SBucket *pSBucket;
209         Audio *audio;
210         AErrorHandler prevHandler;
211         SunHeader *header;
212         long status;
213         char *server;
214         int result;
215
216         /* #### Finish this to return an error code.
217            This function signal a lisp error. How consistent with the rest.
218            What if this function is needed in doing the beep for the error?
219
220            Apparently the author of this didn't read the comment in
221            Fplay_sound.
222          */
223
224         if (STRINGP(Vhp_play_server))
225                 server = (char *)XSTRING_DATA(Vhp_play_server);
226         server = "";
227
228         /* open audio connection */
229         audio = AOpenAudio(server, &status);
230         if (status) {
231                 player_error_internal(audio, "Open audio failed", status);
232         }
233
234         /* replace default error handler */
235         prevHandler = ASetErrorHandler(myHandler);
236
237         /* Create sound bucket */
238         header = (SunHeader *) data;
239
240         pSBucket = ACreateSBucket(audio, NULL, NULL, &status);
241         if (status)
242                 player_error_internal(audio, "Bucket creation failed", status);
243
244         APutSBucketData(audio, pSBucket, 0,
245                         (char *)(data + header->header_size),
246                         header->data_length, &status);
247
248         if (status)
249                 player_error_internal(audio, "Audio data copy failed", status);
250
251         /* Play sound */
252         play_bucket_internal(audio, pSBucket, volume);
253
254         ASetErrorHandler(prevHandler);
255         if (status)
256                 player_error_internal(audio, "Audio data copy failed", status);
257
258         return 1;
259 }
260
261 void vars_of_hpplay(void)
262 {
263         DEFVAR_LISP("hp-play-server", &Vhp_play_server  /*
264 A string, determining which server to play sound at.
265 Note that this is specific to the HP sound implementation, and you should
266 not make your functions depend on it.
267                                                          */ );
268
269         Vhp_play_server = Qnil;
270
271         DEFVAR_LISP("hp-play-speaker", &Vhp_play_speaker        /*
272 If this variable is the symbol `external', sound is played externally.
273 If the environment variable SPEAKER is set, that value is used for
274 initializing this variable.
275 Note that this is specific to the HP sound implementation, and you should
276 not make your functions depend on it.
277                                                                  */ );
278
279         Vhp_play_speaker = intern("internal");
280
281         DEFVAR_INT("hp-play-gain", &hp_play_gain        /*
282 Global gain value for playing sounds.
283 Default value is AUnityGain which means keep level.
284 Please refer to the HP documentation, for instance in
285 `Using the Audio Application Program Interface', for details on how to
286 interpret this variable.
287 Note that this is specific to the HP sound implementation, and you should
288 not make your functions depend on it.
289                                                          */ );
290
291         hp_play_gain = AUnityGain;
292 }
293
294 void init_hpplay(void)
295 {
296         if (getenv("SPEAKER"))
297                 Vhp_play_speaker = intern(getenv("SPEAKER"));
298 }