X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fsound.c;h=7fde90cadb9ac2f2d052629f8dbe4fd5f61a5991;hb=a6c4c0c8d8224cdc455f0d184e91d0cf881f0077;hp=ff0f05b07763ccf27b5e3ca8fe3fea926d428c69;hpb=36eddd2c06ce9b09c83102353deb213e065e901d;p=dockapps%2Fwmnotify.git diff --git a/src/sound.c b/src/sound.c index ff0f05b..7fde90c 100644 --- a/src/sound.c +++ b/src/sound.c @@ -34,7 +34,7 @@ # include # include # include -#elif( defined(sun) && defined(unix) ) +#elif(defined(sun) && defined(unix)) # include # include # include @@ -50,287 +50,313 @@ #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 */