Mercurial > hg > xemacs-beta
comparison src/linuxplay.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 3ecd8885ac67 |
children | 183866b06e0b |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
56 #ifdef HAVE_CONFIG_H | 56 #ifdef HAVE_CONFIG_H |
57 #include <config.h> | 57 #include <config.h> |
58 #endif | 58 #endif |
59 | 59 |
60 #include "miscplay.h" | 60 #include "miscplay.h" |
61 #include "nativesound.h" | |
61 | 62 |
62 #include <errno.h> | 63 #include <errno.h> |
63 #include <fcntl.h> | 64 #include <fcntl.h> |
64 #include SOUNDCARD_H_PATH /* Path computed by configure */ | 65 #include SOUNDCARD_H_FILE /* Path computed by configure */ |
65 #include <stdio.h> | 66 #include <stdio.h> |
66 #include <stdlib.h> | 67 #include <stdlib.h> |
67 #include <string.h> | 68 #include <string.h> |
68 #include <fcntl.h> | 69 #include <fcntl.h> |
69 #include <sys/file.h> | 70 #include <sys/file.h> |
80 #include "sysfile.h" | 81 #include "sysfile.h" |
81 #define perror(str) message("audio: %s, %s ",str,strerror(errno)) | 82 #define perror(str) message("audio: %s, %s ",str,strerror(errno)) |
82 #define warn(str) message("audio: %s ",GETTEXT(str)) | 83 #define warn(str) message("audio: %s ",GETTEXT(str)) |
83 #endif | 84 #endif |
84 | 85 |
85 static void (*sighup_handler)(int); | 86 static SIGTYPE (*sighup_handler) (int); |
86 static void (*sigint_handler)(int); | 87 static SIGTYPE (*sigint_handler) (int); |
87 | 88 |
88 static int mix_fd; | 89 static int mix_fd; |
89 static int audio_vol; | 90 static int audio_vol; |
90 static int audio_fd; | 91 static int audio_fd; |
91 static char *audio_dev = "/dev/dsp"; | 92 static char *audio_dev = "/dev/dsp"; |
92 | 93 |
93 /* Intercept SIGINT and SIGHUP in order to close the audio and mixer | 94 /* Intercept SIGINT and SIGHUP in order to close the audio and mixer |
94 devices before terminating sound output; this requires reliable | 95 devices before terminating sound output; this requires reliable |
95 signals as provided by "syssignal.h" */ | 96 signals as provided by "syssignal.h" */ |
96 static void sighandler(int sig) | 97 static SIGTYPE |
98 sighandler (int sig) | |
97 { | 99 { |
98 if (mix_fd > 0) { | 100 if (mix_fd > 0) { |
99 if (audio_vol >= 0) { | 101 if (audio_vol >= 0) { |
100 ioctl(mix_fd,SOUND_MIXER_WRITE_PCM,&audio_vol); | 102 ioctl(mix_fd,SOUND_MIXER_WRITE_PCM,&audio_vol); |
101 audio_vol = -1; } | 103 audio_vol = -1; } |
274 | 276 |
275 return(1); | 277 return(1); |
276 } | 278 } |
277 | 279 |
278 /* XEmacs requires code both for playback of pre-loaded data and for playback | 280 /* XEmacs requires code both for playback of pre-loaded data and for playback |
279 from a soundfile; we use one function for both cases */ | 281 from a soundfile; we use one function for both cases. |
280 static void linux_play_data_or_file(int fd,unsigned char *data, | 282 |
283 Returns 1 on succes. 0 otherwise. | |
284 */ | |
285 static int linux_play_data_or_file(int fd,unsigned char *data, | |
281 int length,int volume) | 286 int length,int volume) |
282 { | 287 { |
283 size_t (*parsesndfile)(void **dayta,size_t *sz,void **outbuf); | 288 size_t (*parsesndfile)(void **dayta,size_t *sz,void **outbuf); |
284 size_t (*sndcnv)(void **dayta,size_t *sz,void **); | 289 size_t (*sndcnv)(void **dayta,size_t *sz,void **); |
285 fmtType ffmt; | 290 fmtType ffmt; |
289 unsigned char sndbuf[SNDBUFSZ]; | 294 unsigned char sndbuf[SNDBUFSZ]; |
290 | 295 |
291 /* We need to read at least the header information before we can start | 296 /* We need to read at least the header information before we can start |
292 doing anything */ | 297 doing anything */ |
293 if (!data || length < HEADERSZ) { | 298 if (!data || length < HEADERSZ) { |
294 if (fd < 0) return; | 299 if (fd < 0) return 0; |
295 else { | 300 else { |
296 length = read(fd,sndbuf,SNDBUFSZ); | 301 length = read(fd,sndbuf,SNDBUFSZ); |
297 if (length < HEADERSZ) | 302 if (length < HEADERSZ) |
298 return; | 303 return 0; |
299 data = sndbuf; | 304 data = sndbuf; |
300 length = SNDBUFSZ; } | 305 length = SNDBUFSZ; } |
301 } | 306 } |
302 | 307 |
303 ffmt = analyze_format(data,&fmt,&speed,&tracks,&parsesndfile); | 308 ffmt = analyze_format(data,&fmt,&speed,&tracks,&parsesndfile); |
304 | 309 |
305 if (ffmt != fmtRaw && ffmt != fmtSunAudio && ffmt != fmtWave) { | 310 if (ffmt != fmtRaw && ffmt != fmtSunAudio && ffmt != fmtWave) { |
306 warn("Unsupported file format (neither RAW, nor Sun/DECAudio, nor WAVE)"); | 311 warn("Unsupported file format (neither RAW, nor Sun/DECAudio, nor WAVE)"); |
307 return; } | 312 return 0; } |
308 | 313 |
309 /* The VoxWare-SDK discourages opening /dev/audio; opening /dev/dsp and | 314 /* The VoxWare-SDK discourages opening /dev/audio; opening /dev/dsp and |
310 properly initializing it via ioctl() is preferred */ | 315 properly initializing it via ioctl() is preferred */ |
311 if ((audio_fd=open(audio_dev, O_WRONLY | O_NONBLOCK, 0)) < 0) { | 316 if ((audio_fd=open(audio_dev, O_WRONLY | O_NONBLOCK, 0)) < 0) { |
312 perror(audio_dev); | 317 /* JV. Much too verbose. In addition this can crash. See NOTE: in |
318 Fplay_sound | |
319 perror(audio_dev); */ | |
313 if (mix_fd > 0 && mix_fd != audio_fd) { close(mix_fd); mix_fd = -1; } | 320 if (mix_fd > 0 && mix_fd != audio_fd) { close(mix_fd); mix_fd = -1; } |
314 return; } | 321 return 0; } |
315 | 322 |
316 /* The VoxWare-SDK discourages direct manipulation of the mixer device as | 323 /* The VoxWare-SDK discourages direct manipulation of the mixer device as |
317 this could lead to problems, when multiple sound cards are installed */ | 324 this could lead to problems, when multiple sound cards are installed */ |
318 mix_fd = audio_fd; | 325 mix_fd = audio_fd; |
319 | 326 |
353 break; | 360 break; |
354 } while (rrtn > 0); | 361 } while (rrtn > 0); |
355 | 362 |
356 if (ffmt == fmtWave) | 363 if (ffmt == fmtWave) |
357 parse_wave_complete(); | 364 parse_wave_complete(); |
358 | 365 |
359 | 366 |
360 END_OF_PLAY: | 367 END_OF_PLAY: |
361 /* Now cleanup all used resources */ | 368 /* Now cleanup all used resources */ |
362 | 369 |
363 ioctl(audio_fd,SNDCTL_DSP_SYNC,NULL); | 370 ioctl(audio_fd,SNDCTL_DSP_SYNC,NULL); |
375 mix_fd = -1; } | 382 mix_fd = -1; } |
376 | 383 |
377 close(audio_fd); | 384 close(audio_fd); |
378 audio_fd = -1; | 385 audio_fd = -1; |
379 | 386 |
380 return; | 387 return 1; |
381 } | 388 } |
382 | 389 |
383 /* Call "linux_play_data_or_file" with the appropriate parameters for | 390 /* Call "linux_play_data_or_file" with the appropriate parameters for |
384 playing a soundfile */ | 391 playing a soundfile */ |
385 void play_sound_file (char *sound_file, int volume); | |
386 void play_sound_file (char *sound_file, int volume) | 392 void play_sound_file (char *sound_file, int volume) |
387 { | 393 { |
388 int fd; | 394 int fd; |
389 | 395 |
390 if ((fd=open(sound_file,O_RDONLY,0)) < 0) { | 396 if ((fd=open(sound_file,O_RDONLY,0)) < 0) { |
395 return; | 401 return; |
396 } | 402 } |
397 | 403 |
398 /* Call "linux_play_data_or_file" with the appropriate parameters for | 404 /* Call "linux_play_data_or_file" with the appropriate parameters for |
399 playing pre-loaded data */ | 405 playing pre-loaded data */ |
400 void play_sound_data (unsigned char *data, int length, int volume); | 406 int play_sound_data (unsigned char *data, int length, int volume) |
401 void play_sound_data (unsigned char *data, int length, int volume) | |
402 { | 407 { |
403 linux_play_data_or_file(-1,data,length,volume); | 408 return linux_play_data_or_file(-1,data,length,volume); |
404 return; | |
405 } | 409 } |