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