update.
[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      attempt 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 "nativesound.h"
55
56 #include <stdlib.h>
57 #include <stdio.h>
58 #ifdef HPUX10
59 #include <Alib.h>
60 #include <CUlib.h>
61 #else /* !HPUX 10 */
62 #include <audio/Alib.h>
63 #include <audio/CUlib.h>
64 #endif /* !HPUX 10 */
65
66
67 Lisp_Object Vhp_play_server;
68 Lisp_Object Vhp_play_speaker;
69 Fixnum      hp_play_gain;
70
71 /* Functions */
72
73 /* error handling */
74 void player_error_internal(
75     Audio        * audio,
76     char         * text,
77     long         errorCode
78     )
79 {
80     char    errorbuff[132],buf[256];
81
82     AGetErrorText(audio, errorCode, errorbuff, 131);
83     sprintf(buf,"%s: %s\n",text,errorbuff);
84     error(buf);
85 }
86
87 long myHandler(audio, err_event)
88     Audio  * audio;
89     AErrorEvent  * err_event;
90 {
91   player_error_internal(audio, "Internal sound error", err_event->error_code);
92   return 1;                     /* Must return something, was orig. an exit */
93 }
94
95 /* Playing */
96 void
97 play_bucket_internal(audio, pSBucket, volume)
98      Audio           *audio;
99      SBucket     *pSBucket;
100      long         volume;
101 {
102     SBPlayParams    playParams;
103     AGainEntry      gainEntry;
104     ATransID        xid;
105     long            status;
106     char            * speaker;
107
108     playParams.priority = APriorityNormal;          /* normal priority */
109
110     /*
111      * We can't signal an error, because all h*ll would break loose if
112      * we did.
113      */
114     if (SYMBOLP (Vhp_play_speaker))
115     {
116         speaker = (char *) (string_data (XSYMBOL (Vhp_play_speaker)->name));
117
118         /*
119          * setup the playback parameters
120          */
121
122         /* speaker selection */
123         if ( strcmp(speaker,"external") == 0 ) {
124             gainEntry.u.o.out_dst = AODTMonoJack;
125         } else {
126             gainEntry.u.o.out_dst = AODTMonoIntSpeaker;
127         }
128     }
129     else
130     {
131         /*
132          * Quietly revert to the internal speaker
133          */
134         gainEntry.u.o.out_dst = AODTMonoIntSpeaker;
135     }
136
137     gainEntry.u.o.out_ch = AOCTMono;
138     gainEntry.gain = AUnityGain;
139     playParams.gain_matrix.type = AGMTOutput;       /* gain matrix */
140     playParams.gain_matrix.num_entries = 1;
141     playParams.gain_matrix.gain_entries = &gainEntry;
142     playParams.play_volume = hp_play_gain;          /* play volume */
143     playParams.pause_first = False;                 /* don't pause */
144     playParams.start_offset.type = ATTSamples;      /* start offset 0 */
145     playParams.start_offset.u.samples = 0;
146     playParams.duration.type = ATTFullLength;       /* play entire sample */
147     playParams.loop_count = 1;                      /* play sample just once */
148     playParams.previous_transaction = 0;            /* no linked transaction */
149     playParams.event_mask = 0;                      /* don't solicit any events */
150
151     /*
152      * play the sound bucket
153      */
154     xid = APlaySBucket( audio, pSBucket, &playParams, NULL );
155
156     /*
157      * set close mode to prevent playback from stopping
158      *  when we close audio connection
159      */
160     ASetCloseDownMode( audio, AKeepTransactions, &status );
161
162     /*
163      *  That's all, folks!
164      *  Always destroy bucket and close connection.
165      */
166     ADestroySBucket( audio, pSBucket, &status );
167     ACloseAudio( audio, &status );
168 }
169
170 void
171 play_sound_file (sound_file, volume)
172      char * sound_file;
173      int volume;
174 {
175     SBucket         *pSBucket;
176     Audio           *audio;
177     long            status;
178     AErrorHandler   prevHandler;  /* pointer to previous handler */
179     char            *server;
180
181     if (STRINGP(Vhp_play_server))
182       server = (char *) XSTRING_DATA (Vhp_play_server);
183     server = "";
184
185     /*
186      *  open audio connection
187      */
188     audio = AOpenAudio( server, &status );
189     if( status ) {
190         player_error_internal( audio, "Open audio failed", status );
191     }
192
193     /* replace default error handler */
194     prevHandler = ASetErrorHandler(myHandler);
195
196     /*
197      *  Load the audio file into a sound bucket
198      */
199
200     pSBucket = ALoadAFile( audio, sound_file, AFFUnknown, 0, NULL, NULL );
201
202     /*
203      * Play the bucket
204      */
205
206     play_bucket_internal(audio, pSBucket, volume);
207
208     ASetErrorHandler(prevHandler);    
209 }
210
211
212 int
213 play_sound_data (data, length, volume)
214      unsigned char * data;
215      int length;
216      int volume;
217 {
218     SBucket         *pSBucket;
219     Audio           *audio;
220     AErrorHandler   prevHandler;
221     SunHeader       *header;
222     long            status;
223     char            *server;
224     int             result;
225
226     /* #### Finish this to return an error code.
227        This function signal a lisp error. How consistent with the rest.
228        What if this function is needed in doing the beep for the error?
229
230        Apparently the author of this didn't read the comment in
231        Fplay_sound.
232     */
233        
234     
235     if (STRINGP (Vhp_play_server))
236       server = (char *) XSTRING_DATA (Vhp_play_server);
237     server = "";
238
239     /* open audio connection */
240     audio = AOpenAudio( server, &status );
241     if( status ) {
242         player_error_internal( audio, "Open audio failed", status );
243     }
244
245     /* replace default error handler */
246     prevHandler = ASetErrorHandler (myHandler);
247
248     /* Create sound bucket */
249     header = (SunHeader *) data;
250
251     pSBucket = ACreateSBucket(audio, NULL, NULL, &status);
252     if (status)
253       player_error_internal( audio, "Bucket creation failed", status );
254
255     APutSBucketData(audio, pSBucket, 0, (char *) (data + header->header_size), header->data_length, &status);
256
257    if (status)
258       player_error_internal( audio, "Audio data copy failed", status );
259
260     /* Play sound */
261     play_bucket_internal(audio, pSBucket, volume);
262
263     ASetErrorHandler(prevHandler);
264     if (status)
265       player_error_internal( audio, "Audio data copy failed", status );
266
267     return 1;
268 }
269
270 void
271 vars_of_hpplay (void)
272 {
273   DEFVAR_LISP ("hp-play-server", &Vhp_play_server /*
274 A string, determining which server to play sound at.
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_server = Qnil;
280
281   DEFVAR_LISP ("hp-play-speaker", &Vhp_play_speaker /*
282 If this variable is the symbol `external', sound is played externally.
283 If the environment variable SPEAKER is set, that value is used for
284 initializing this variable.
285 Note that this is specific to the HP sound implementation, and you should
286 not make your functions depend on it.
287 */ );
288
289   Vhp_play_speaker = intern ("internal");
290
291   DEFVAR_INT("hp-play-gain", &hp_play_gain /*
292 Global gain value for playing sounds.
293 Default value is AUnityGain which means keep level.
294 Please refer to the HP documentation, for instance in
295 `Using the Audio Application Program Interface', for details on how to
296 interpret this variable.
297 Note that this is specific to the HP sound implementation, and you should
298 not make your functions depend on it.
299 */ );
300
301   hp_play_gain = AUnityGain;
302 }
303
304 void
305 init_hpplay (void)
306 {
307   if (getenv ("SPEAKER"))
308     Vhp_play_speaker = intern (getenv ("SPEAKER"));
309 }