-/* sound.c */
-
-/* Plays sound from file. Based on the 'sndfile-play' demo program from 'libsndfile' */
-
+/*
+ * sound.c -- Plays sound from file.
+ *
+ * Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
+ * Based on the 'sndfile-play' demo program from 'libsndfile'
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
#if HAVE_CONFIG_H
# include "config.h"
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/soundcard.h>
-#elif( defined(sun) && defined(unix) )
+#elif(defined(sun) && defined(unix))
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/audioio.h>
#define BUFFER_LEN ((sf_count_t) 2048)
-static int
-OpenDspDevice( int channels, int srate )
+static int OpenDspDevice(int channels, int srate)
{
- int fd, status;
-#if defined (__linux__)
- int stereo, temp;
- const char audio_device[] = "/dev/dsp";
-#elif( defined(sun) && defined(unix) )
- audio_info_t audio_info;
- const char audio_device[] = "/dev/audio";
+ int fd, status;
+#if defined(__linux__)
+ int stereo, temp;
+ const char audio_device[] = "/dev/dsp";
+#elif(defined(sun) && defined(unix))
+ audio_info_t audio_info;
+ const char audio_device[] = "/dev/audio";
#endif
-
-#if defined (__linux__)
- fd = open( audio_device, O_WRONLY, 0 );
-#elif( defined(sun) && defined(unix) )
- /* Open the audio device - write only, non-blocking */
- fd = open( audio_device, O_WRONLY | O_NONBLOCK );
+
+#if defined(__linux__)
+ fd = open(audio_device, O_WRONLY, 0);
+#elif(defined(sun) && defined(unix))
+ /* Open the audio device - write only, non-blocking */
+ fd = open(audio_device, O_WRONLY | O_NONBLOCK);
#endif
-
- if( fd < 0 ) {
- fprintf( stderr, "%s: open() failed trying to open device '%s':\n", PACKAGE,
- audio_device );
- fprintf( stderr, " %s\n", strerror( errno ) );
- fprintf( stderr,
- " Check if device file exists and has correct write permissions.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- return -1;
- }
-
-#if defined (__linux__)
- stereo = 0;
- status = ioctl( fd, SNDCTL_DSP_STEREO, &stereo );
- if( status == -1 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SNDCTL_DSP_RESET, 0 );
- if( status > 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- temp = 16;
- status = ioctl( fd, SOUND_PCM_WRITE_BITS, &temp );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SOUND_PCM_WRITE_CHANNELS, &channels );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SOUND_PCM_WRITE_RATE, &srate );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SNDCTL_DSP_SYNC, 0 );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
-#elif( defined(sun) && defined(unix) )
- /* Retrieve standard values. */
- AUDIO_INITINFO( &audio_info );
-
- audio_info.play.sample_rate = sfinfo.samplerate;
- audio_info.play.channels = sfinfo.channels;
- audio_info.play.precision = 16;
- audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
- audio_info.play.gain = AUDIO_MAX_GAIN;
- audio_info.play.balance = AUDIO_MID_BALANCE;
-
- status = ioctl( audio_fd, AUDIO_SETINFO, &audio_info );
- if( status > 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
+
+ if (fd < 0) {
+ fprintf(stderr,
+ "%s: open() failed trying to open device '%s':\n",
+ PACKAGE, audio_device);
+ fprintf(stderr, " %s\n", strerror(errno));
+ fprintf(stderr,
+ " Check if device file exists and has correct write permissions.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ return -1;
+ }
+#if defined(__linux__)
+ stereo = 0;
+ status = ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
+ if (status == -1) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SNDCTL_DSP_RESET, 0);
+ if (status > 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ temp = 16;
+ status = ioctl(fd, SOUND_PCM_WRITE_BITS, &temp);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &channels);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SOUND_PCM_WRITE_RATE, &srate);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SNDCTL_DSP_SYNC, 0);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+#elif(defined(sun) && defined(unix))
+ /* Retrieve standard values. */
+ AUDIO_INITINFO(&audio_info);
+
+ audio_info.play.sample_rate = sfinfo.samplerate;
+ audio_info.play.channels = sfinfo.channels;
+ audio_info.play.precision = 16;
+ audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
+ audio_info.play.gain = AUDIO_MAX_GAIN;
+ audio_info.play.balance = AUDIO_MID_BALANCE;
+
+ status = ioctl(audio_fd, AUDIO_SETINFO, &audio_info);
+ if (status > 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
#endif
-
- return fd;
+
+ return fd;
}
-void
-PlayAudioFile( char *filename, int volume )
+void PlayAudioFile(char *filename, int volume)
{
- static short buffer[BUFFER_LEN];
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- int audio_fd;
- int readcount;
- int status;
-#if defined (__linux__)
- int subformat;
- int m;
-#elif( defined(sun) && defined(unix) )
- unsigned long delay_time;
- long start_count, output_count, write_count;
- bool done;
+ static short buffer[BUFFER_LEN];
+ SNDFILE *sndfile;
+ SF_INFO sfinfo;
+ int audio_fd;
+ int readcount;
+ int status;
+#if defined(__linux__)
+ int subformat;
+ int m;
+#elif(defined(sun) && defined(unix))
+ unsigned long delay_time;
+ long start_count, output_count, write_count;
+ bool done;
#endif
- if( wmnotify_infos.debug ) {
- printf( "%s: PlayAudioFile() Entry\n", PACKAGE );
- }
-
- if( filename == NULL ) {
- fprintf( stderr, "%s: No audio file specified.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- sndfile = sf_open( filename, SFM_READ, &sfinfo );
-
- if( sndfile == NULL ) {
- fprintf( stderr, "%s: sf_open() failed trying to open '%s':\n", PACKAGE, filename );
- fprintf( stderr, " %s\n", sf_strerror(NULL) );
- fprintf( stderr, " Check if file exists and has correct read permissions.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- return;
- }
-
- if( sfinfo.channels < 1 || sfinfo.channels > 2 ) {
- fprintf( stderr, "%s: Audio file has %d channel(s), but ", PACKAGE, sfinfo.channels );
- fprintf( stderr, "we support only 1 or 2 channels.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- audio_fd = OpenDspDevice( sfinfo.channels, sfinfo.samplerate );
- if( audio_fd < 0 ) {
- goto play_audio_file_close_file;
- }
-
-#if( defined(sun) && defined(unix) )
- /* Delay time equal to 1/4 of a buffer in microseconds. */
- delay_time = (BUFFER_LEN * 1000000) / (sfinfo.samplerate * 4);
-#endif
+ if (wmnotify_infos.debug)
+ printf("%s: PlayAudioFile() Entry\n", PACKAGE);
- subformat = sfinfo.format & SF_FORMAT_SUBMASK;
-
- if( subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE ) {
- static float flt_buffer[BUFFER_LEN];
- double scale;
-
- status = sf_command( sndfile, SFC_CALC_SIGNAL_MAX, &scale, (int) sizeof(scale) );
- if( status == 0 ) {
- fprintf( stderr, "%s: Warning, sf_command() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- if (scale < 1e-10) {
- scale = 1.0;
- }
- else {
- scale = 32700.0 / scale;
- }
-
- while( ( readcount = (int) sf_read_float( sndfile, flt_buffer, BUFFER_LEN ) ) != 0 ) {
- /* Linux/OSS -- FLOAT samples */
-#if defined (__linux__)
- for( m = 0 ; m < readcount ; m++ ) {
- /* Float to integer conversion. */
- buffer[m] = (short) ( scale * flt_buffer[m] );
- /* Changing volume */
- buffer[m] = buffer[m] * volume / 100;
- }
- status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
- if( status == -1 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- /* Solaris -- FLOAT samples */
-#elif( defined(sun) && defined(unix) )
- start_count = 0;
- output_count = read_count * sizeof(short);
-
- while( output_count > 0 ) {
- /* Write as much data as possible */
- for( m = 0 ; m < readcount ; m++ ) {
- /* Float to integer conversion. */
- buffer[m] = (short) ( scale * flt_buffer[m] );
- /* Changing volume */
- buffer[m] = buffer[m] * volume / 100;
+ if (filename == NULL) {
+ fprintf(stderr, "%s: No audio file specified.\n", PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
-
- write_count = write( audio_fd, &(buffer[start_count]), output_count );
- if( write_count > 0 ) {
- output_count -= write_count;
- start_count += write_count;
+
+ sndfile = sf_open(filename, SFM_READ, &sfinfo);
+
+ if (sndfile == NULL) {
+ fprintf(stderr,
+ "%s: sf_open() failed trying to open '%s':\n",
+ PACKAGE, filename);
+ fprintf(stderr, " %s\n", sf_strerror(NULL));
+ fprintf(stderr,
+ " Check if file exists and has correct read permissions.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ return;
}
- else {
- /* Give the audio output time to catch up. */
- usleep( delay_time );
+
+ if (sfinfo.channels < 1 || sfinfo.channels > 2) {
+ fprintf(stderr, "%s: Audio file has %d channel(s), but ",
+ PACKAGE, sfinfo.channels);
+ fprintf(stderr, "we support only 1 or 2 channels.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- } /* while( output_count > 0 ) */
+
+ audio_fd = OpenDspDevice(sfinfo.channels, sfinfo.samplerate);
+ if (audio_fd < 0)
+ goto play_audio_file_close_file;
+
+#if (defined(sun) && defined(unix))
+ /* Delay time equal to 1/4 of a buffer in microseconds. */
+ delay_time = (BUFFER_LEN * 1000000) / (sfinfo.samplerate * 4);
#endif
- } /* while( ( readcount... ) */
- }
- else {
- while( ( readcount = (int) sf_read_short( sndfile, buffer, BUFFER_LEN ) ) != 0 ) {
- /* Linux/OSS -- INTEGER samples */
-#if defined (__linux__)
- /* Changing volume... */
- for( m = 0 ; m < readcount ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
- if( status == -1 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- /* Solaris -- INTEGER samples */
-#elif( defined(sun) && defined(unix) )
- start_count = 0;
- output_count = read_count * sizeof(short);
-
- while( output_count > 0 ) {
- /* Write as much data as possible */
-
- /* Changing volume. */
- for( m = 0 ; m < read_count ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- write_count = write( audio_fd, &(buffer[start_count]), output_count );
- if( write_count > 0 ) {
- output_count -= write_count;
- start_count += write_count;
+
+ subformat = sfinfo.format & SF_FORMAT_SUBMASK;
+
+ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
+ static float flt_buffer[BUFFER_LEN];
+ double scale;
+
+ status =
+ sf_command(sndfile, SFC_CALC_SIGNAL_MAX, &scale,
+ (int) sizeof(scale));
+ if (status == 0) {
+ fprintf(stderr,
+ "%s: Warning, sf_command() failed.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ if (scale < 1e-10)
+ scale = 1.0;
+ else
+ scale = 32700.0 / scale;
+
+ while ((readcount =
+ (int) sf_read_float(sndfile, flt_buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- FLOAT samples */
+#if defined(__linux__)
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale * flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] = buffer[m] * volume / 100;
+ }
+ status =
+ (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- FLOAT samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale *
+ flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] =
+ buffer[m] * volume / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } else {
+ while ((readcount =
+ (int) sf_read_short(sndfile, buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- INTEGER samples */
+#if defined(__linux__)
+ /* Changing volume... */
+ for (m = 0; m < readcount; m++)
+ buffer[m] = (buffer[m] * volume) / 100;
+
+ status = (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- INTEGER samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+
+ /* Changing volume. */
+ for (m = 0; m < read_count; m++) {
+ buffer[m] =
+ (buffer[m] * volume) / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } /* else */
+
+play_audio_file_close_audio:
+
+ status = close(audio_fd);
+ if (status != 0) {
+ fprintf(stderr, "%s: Error, close() failed.\n", PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- else {
- /* Give the audio output time to catch up. */
- usleep( delay_time );
+
+play_audio_file_close_file:
+
+ status = sf_close(sndfile);
+ if (status != 0) {
+ fprintf(stderr, "%s: Error, sf_close() failed.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- } /* while( output_count > 0 ) */
-#endif
- } /* while( ( readcount... ) */
- } /* else */
-
- play_audio_file_close_audio:
-
- status = close( audio_fd );
- if( status != 0 ) {
- fprintf( stderr, "%s: Error, close() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- play_audio_file_close_file:
-
- status = sf_close( sndfile );
- if( status != 0 ) {
- fprintf( stderr, "%s: Error, sf_close() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- if( wmnotify_infos.debug ) {
- printf( "%s: PlayAudioFile() Exit\n", PACKAGE );
- }
-
- return;
+
+ if (wmnotify_infos.debug)
+ printf("%s: PlayAudioFile() Exit\n", PACKAGE);
+
+ return;
}
#endif /* HAVE_SNDFILE */