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 }